1%% Copyright (c) 2013-2014, Loïc Hoguin <essen@ninenines.eu> 2%% 3%% Permission to use, copy, modify, and/or distribute this software for any 4%% purpose with or without fee is hereby granted, provided that the above 5%% copyright notice and this permission notice appear in all copies. 6%% 7%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 15-module(cow_date). 16 17-export([rfc2109/1]). 18 19%% @doc Return the date formatted according to RFC2109. 20 21-spec rfc2109(calendar:datetime()) -> binary(). 22rfc2109({Date = {Y, Mo, D}, {H, Mi, S}}) -> 23 Wday = calendar:day_of_the_week(Date), 24 << (weekday(Wday))/binary, ", ", 25 (pad_int(D))/binary, "-", 26 (month(Mo))/binary, "-", 27 (year(Y))/binary, " ", 28 (pad_int(H))/binary, ":", 29 (pad_int(Mi))/binary, ":", 30 (pad_int(S))/binary, " GMT" >>. 31 32-ifdef(TEST). 33rfc2109_test_() -> 34 Tests = [ 35 {<<"Sat, 14-May-2011 14:25:33 GMT">>, {{2011, 5, 14}, {14, 25, 33}}}, 36 {<<"Sun, 01-Jan-2012 00:00:00 GMT">>, {{2012, 1, 1}, { 0, 0, 0}}} 37 ], 38 [{R, fun() -> R = rfc2109(D) end} || {R, D} <- Tests]. 39-endif. 40 41-ifdef(PERF). 42horse_rfc2019_20130101_000000() -> 43 horse:repeat(100000, 44 rfc2109({{2013, 1, 1}, {0, 0, 0}}) 45 ). 46 47horse_rfc2019_20131231_235959() -> 48 horse:repeat(100000, 49 rfc2109({{2013, 12, 31}, {23, 59, 59}}) 50 ). 51 52horse_rfc2019_12340506_070809() -> 53 horse:repeat(100000, 54 rfc2109({{1234, 5, 6}, {7, 8, 9}}) 55 ). 56-endif. 57 58%% Internal. 59 60-spec pad_int(0..59) -> <<_:16>>. 61pad_int( 0) -> <<"00">>; 62pad_int( 1) -> <<"01">>; 63pad_int( 2) -> <<"02">>; 64pad_int( 3) -> <<"03">>; 65pad_int( 4) -> <<"04">>; 66pad_int( 5) -> <<"05">>; 67pad_int( 6) -> <<"06">>; 68pad_int( 7) -> <<"07">>; 69pad_int( 8) -> <<"08">>; 70pad_int( 9) -> <<"09">>; 71pad_int(10) -> <<"10">>; 72pad_int(11) -> <<"11">>; 73pad_int(12) -> <<"12">>; 74pad_int(13) -> <<"13">>; 75pad_int(14) -> <<"14">>; 76pad_int(15) -> <<"15">>; 77pad_int(16) -> <<"16">>; 78pad_int(17) -> <<"17">>; 79pad_int(18) -> <<"18">>; 80pad_int(19) -> <<"19">>; 81pad_int(20) -> <<"20">>; 82pad_int(21) -> <<"21">>; 83pad_int(22) -> <<"22">>; 84pad_int(23) -> <<"23">>; 85pad_int(24) -> <<"24">>; 86pad_int(25) -> <<"25">>; 87pad_int(26) -> <<"26">>; 88pad_int(27) -> <<"27">>; 89pad_int(28) -> <<"28">>; 90pad_int(29) -> <<"29">>; 91pad_int(30) -> <<"30">>; 92pad_int(31) -> <<"31">>; 93pad_int(32) -> <<"32">>; 94pad_int(33) -> <<"33">>; 95pad_int(34) -> <<"34">>; 96pad_int(35) -> <<"35">>; 97pad_int(36) -> <<"36">>; 98pad_int(37) -> <<"37">>; 99pad_int(38) -> <<"38">>; 100pad_int(39) -> <<"39">>; 101pad_int(40) -> <<"40">>; 102pad_int(41) -> <<"41">>; 103pad_int(42) -> <<"42">>; 104pad_int(43) -> <<"43">>; 105pad_int(44) -> <<"44">>; 106pad_int(45) -> <<"45">>; 107pad_int(46) -> <<"46">>; 108pad_int(47) -> <<"47">>; 109pad_int(48) -> <<"48">>; 110pad_int(49) -> <<"49">>; 111pad_int(50) -> <<"50">>; 112pad_int(51) -> <<"51">>; 113pad_int(52) -> <<"52">>; 114pad_int(53) -> <<"53">>; 115pad_int(54) -> <<"54">>; 116pad_int(55) -> <<"55">>; 117pad_int(56) -> <<"56">>; 118pad_int(57) -> <<"57">>; 119pad_int(58) -> <<"58">>; 120pad_int(59) -> <<"59">>. 121 122-spec weekday(1..7) -> <<_:24>>. 123weekday(1) -> <<"Mon">>; 124weekday(2) -> <<"Tue">>; 125weekday(3) -> <<"Wed">>; 126weekday(4) -> <<"Thu">>; 127weekday(5) -> <<"Fri">>; 128weekday(6) -> <<"Sat">>; 129weekday(7) -> <<"Sun">>. 130 131-spec month(1..12) -> <<_:24>>. 132month( 1) -> <<"Jan">>; 133month( 2) -> <<"Feb">>; 134month( 3) -> <<"Mar">>; 135month( 4) -> <<"Apr">>; 136month( 5) -> <<"May">>; 137month( 6) -> <<"Jun">>; 138month( 7) -> <<"Jul">>; 139month( 8) -> <<"Aug">>; 140month( 9) -> <<"Sep">>; 141month(10) -> <<"Oct">>; 142month(11) -> <<"Nov">>; 143month(12) -> <<"Dec">>. 144 145-spec year(pos_integer()) -> <<_:32>>. 146year(1970) -> <<"1970">>; 147year(1971) -> <<"1971">>; 148year(1972) -> <<"1972">>; 149year(1973) -> <<"1973">>; 150year(1974) -> <<"1974">>; 151year(1975) -> <<"1975">>; 152year(1976) -> <<"1976">>; 153year(1977) -> <<"1977">>; 154year(1978) -> <<"1978">>; 155year(1979) -> <<"1979">>; 156year(1980) -> <<"1980">>; 157year(1981) -> <<"1981">>; 158year(1982) -> <<"1982">>; 159year(1983) -> <<"1983">>; 160year(1984) -> <<"1984">>; 161year(1985) -> <<"1985">>; 162year(1986) -> <<"1986">>; 163year(1987) -> <<"1987">>; 164year(1988) -> <<"1988">>; 165year(1989) -> <<"1989">>; 166year(1990) -> <<"1990">>; 167year(1991) -> <<"1991">>; 168year(1992) -> <<"1992">>; 169year(1993) -> <<"1993">>; 170year(1994) -> <<"1994">>; 171year(1995) -> <<"1995">>; 172year(1996) -> <<"1996">>; 173year(1997) -> <<"1997">>; 174year(1998) -> <<"1998">>; 175year(1999) -> <<"1999">>; 176year(2000) -> <<"2000">>; 177year(2001) -> <<"2001">>; 178year(2002) -> <<"2002">>; 179year(2003) -> <<"2003">>; 180year(2004) -> <<"2004">>; 181year(2005) -> <<"2005">>; 182year(2006) -> <<"2006">>; 183year(2007) -> <<"2007">>; 184year(2008) -> <<"2008">>; 185year(2009) -> <<"2009">>; 186year(2010) -> <<"2010">>; 187year(2011) -> <<"2011">>; 188year(2012) -> <<"2012">>; 189year(2013) -> <<"2013">>; 190year(2014) -> <<"2014">>; 191year(2015) -> <<"2015">>; 192year(2016) -> <<"2016">>; 193year(2017) -> <<"2017">>; 194year(2018) -> <<"2018">>; 195year(2019) -> <<"2019">>; 196year(2020) -> <<"2020">>; 197year(2021) -> <<"2021">>; 198year(2022) -> <<"2022">>; 199year(2023) -> <<"2023">>; 200year(2024) -> <<"2024">>; 201year(2025) -> <<"2025">>; 202year(2026) -> <<"2026">>; 203year(2027) -> <<"2027">>; 204year(2028) -> <<"2028">>; 205year(2029) -> <<"2029">>; 206year(Year) -> list_to_binary(integer_to_list(Year)). 207