From 5a790ab4ee7343693a76f785b41d8a79ddb79983 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Mon, 29 Apr 2013 18:55:36 -0500 Subject: [PATCH] Make argument order more consistent --- README.markdown | 13 ++++++++++--- src/qdate.erl | 51 +++++++++++++++++++++++++++++++------------------ 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/README.markdown b/README.markdown index 87c1f9a..10d3430 100644 --- a/README.markdown +++ b/README.markdown @@ -59,12 +59,18 @@ T, Z, r, and c), `qdate` will handle them for us. is intelligently determined (see below) + `to_string(FormatString)` - same as `to_string/2`. but uses the current time as `Date` - + `to_date(Date, ToTimezone)` - converts any date/time format to Erlang date + + `to_date(ToTimezone, Date)` - converts any date/time format to Erlang date format. Will first convert the date to the timezone `ToTimezone`. + `to_date(Date)` - same as `to_date/2`, but the timezone is determined (see below). + `to_now(Date)` - converts any date/time format to Erlang now format. + `to_unixtime(Date)` - converts any date/time format to a unixtime integer +**A Note About Argument Order**: In all cases, `ToTimezone` is optional and if +omitted, will be determined as described below in "Understanding Timezone +Determining and Conversion". If `ToTimezone` is specified, it will always be +immediately left of the `Date` argument. `Date` will always be the last +argument to any of the conversion and formatting functions. + #### Understanding Timezone Determining and Conversions There is a lot of timezone inferring going on here. @@ -364,7 +370,7 @@ ok %% Since we cleared the timezone for the current process, it just used "GMT" %% Let's get the date again, but this time, use to the Timezone key `my_site` -29> qdate:to_date(DateUnix, my_site). +29> qdate:to_date(my_site, DateUnix). {{2013,12,21},{6,24,0}} %% And let's format it to show again the timezone offset @@ -372,7 +378,7 @@ ok "2013-12-21 06:24 -06:00" %% Finally, let's get the date using the User's timezone key -31> qdate:to_date(DateUnix, {user,1}). +31> qdate:to_date({user,1}, DateUnix). {{2013,12,21},{23,24,0}} %% And again, formatted to show the timezone offset @@ -433,6 +439,7 @@ not exist. + Make `qdate` backend-agnostic (allow specifying either ec_date or dh_date as the backend) + Add `-spec` and `-type` info for dialyzer ++ Add date and time arithmetic. ## Conclusion diff --git a/src/qdate.erl b/src/qdate.erl index fa4170b..25df237 100644 --- a/src/qdate.erl +++ b/src/qdate.erl @@ -4,6 +4,11 @@ % -module(qdate). +-export([ + start/0, + stop/0 +]). + -export([ to_string/1, to_string/2, @@ -58,6 +63,11 @@ -define(DETERMINE_TZ, determine_timezone()). +start() -> + application:start(qdate). + +stop() -> + application:stop(qdate). to_string(Format) -> to_string(Format, now()). @@ -81,7 +91,7 @@ to_string(Format, ToTZ, Date) when is_list(Format) -> %% Then we can pass it on to to_date as well. That way we don't have %% to do it twice, since it's already ensured. ActualToTZ = ensure_timezone(ToTZ), - to_string_worker(Format, ActualToTZ, to_date(Date,ActualToTZ)). + to_string_worker(Format, ActualToTZ, to_date(ActualToTZ, Date)). to_string_worker([], _, _) -> ""; @@ -95,7 +105,7 @@ to_string_worker([$I|RestFormat], ToTZ, Date) -> end, I ++ to_string_worker(RestFormat, ToTZ, Date); to_string_worker([H | RestFormat], ToTZ, Date) when H==$O orelse H==$P -> - Shift = get_timezone_shift(Date, ToTZ), + Shift = get_timezone_shift(ToTZ, Date), Separator = case H of $O -> ""; $P -> ":" @@ -105,7 +115,7 @@ to_string_worker([$T | RestFormat], ToTZ, Date) -> {ShortName,_} = localtime:tz_name(Date, ToTZ), ShortName ++ to_string_worker(RestFormat, ToTZ, Date); to_string_worker([$Z | RestFormat], ToTZ, Date) -> - {Sign, Hours, Mins} = get_timezone_shift(Date, ToTZ), + {Sign, Hours, Mins} = get_timezone_shift(ToTZ, Date), Seconds = (Hours * 3600) + (Mins * 60), atom_to_list(Sign) ++ integer_to_list(Seconds) ++ to_string_worker(RestFormat, ToTZ, Date); to_string_worker([$r | RestFormat], ToTZ, Date) -> @@ -133,7 +143,7 @@ leading_zero(I) when I < 10 -> leading_zero(I) -> integer_to_list(I). -get_timezone_shift(Date, TZ) -> +get_timezone_shift(TZ, Date) -> case localtime:tz_shift(Date, TZ) of unable_to_detect -> {error,unable_to_detect}; {error,T} -> {error,T}; @@ -156,11 +166,13 @@ nparse(String) -> to_date(RawDate) -> - to_date(RawDate, ?DETERMINE_TZ). + to_date(?DETERMINE_TZ, RawDate). -to_date(RawDate, ToTZ) when is_binary(RawDate) -> - to_date(binary_to_list(RawDate), ToTZ); -to_date(RawDate, ToTZ) -> +to_date(ToTZ, RawDate) when is_binary(RawDate) -> + to_date(ToTZ, binary_to_list(RawDate)); +to_date(ToTZ, RawDate) when is_binary(ToTZ) -> + to_date(binary_to_list(ToTZ), RawDate); +to_date(ToTZ, RawDate) -> {ExtractedDate, ExtractedTZ} = extract_timezone(RawDate), {RawDate3, FromTZ} = case try_registered_parsers(RawDate) of undefined -> @@ -305,7 +317,7 @@ to_unixtime({MegaSecs,Secs,_}) -> MegaSecs*1000000 + Secs; to_unixtime(ToParse) -> %% We want to treat all unixtimes as GMT - Date = to_date(ToParse, "GMT"), + Date = to_date("GMT", ToParse), calendar:datetime_to_gregorian_seconds(Date) - ?UNIXTIME_BASE. unixtime() -> @@ -388,8 +400,8 @@ tz_tests(_) -> ?_assertEqual(?SELF_TZ,get_timezone()), ?_assertEqual(?USER_TZ,get_timezone(?USER_KEY)), ?_assertEqual(?SITE_TZ,get_timezone(?SITE_KEY)), - ?_assertEqual({{2013,3,7},{0,0,0}}, to_date("3/7/2013 1:00am EST",?USER_KEY)), - ?_assertEqual({{2013,3,7},{0,0,0}}, to_date("3/7/2013 3:00am EST",?SITE_KEY)), + ?_assertEqual({{2013,3,7},{0,0,0}}, to_date(?USER_KEY,"3/7/2013 1:00am EST")), + ?_assertEqual({{2013,3,7},{0,0,0}}, to_date(?SITE_KEY,"3/7/2013 3:00am EST")), ?_assertEqual({{2013,3,7},{2,0,0}}, to_date("3/7/2013 1:00am CST")), %% will use the current pid's setting ?_assertEqual("America/Chicago",to_string("e","America/Chicago","3/7/2013 1:00am")), ?_assertEqual("-0500",to_string("O","EST","3/7/2013 1:00am CST")), @@ -400,13 +412,13 @@ tz_tests(_) -> ?_assertEqual("Thu, 07 Mar 2013 13:15:00 -0500", to_string("r","EST", "3/7/2013 1:15:00pm")), ?_assertEqual("2013-03-07T13:15:00-05:00", to_string("c", "EST", "3/7/2013 1:15:00pm")), - ?_assertEqual({{2013,3,7},{6,0,0}}, to_date("3/7/2013 12:00am -0600","GMT")), - ?_assertEqual({{2013,3,7},{6,0,0}}, to_date("3/7/2013 12:00am -600","GMT")), - ?_assertEqual({{2013,3,7},{6,0,0}}, to_date("3/7/2013 12:00am GMT-0600","GMT")), - ?_assertEqual({{2013,3,7},{6,0,0}}, to_date("3/7/2013 12:00am utc-0600","GMT")), - ?_assertEqual({{2013,3,7},{1,0,0}}, to_date("3/7/2013 12:00am utc-0600","EST")), - ?_assertEqual({{2013,3,6},{18,0,0}}, to_date("3/7/2013 12:00am +0600","GMT")), - ?_assertEqual({{2013,3,6},{12,0,0}}, to_date("3/7/2013 12:00am +0600","CST")), + ?_assertEqual({{2013,3,7},{6,0,0}}, to_date("GMT","3/7/2013 12:00am -0600")), + ?_assertEqual({{2013,3,7},{6,0,0}}, to_date("GMT","3/7/2013 12:00am -600")), + ?_assertEqual({{2013,3,7},{6,0,0}}, to_date("GMT","3/7/2013 12:00am GMT-0600")), + ?_assertEqual({{2013,3,7},{6,0,0}}, to_date("GMT","3/7/2013 12:00am utc-0600")), + ?_assertEqual({{2013,3,7},{1,0,0}}, to_date("EST","3/7/2013 12:00am utc-0600")), + ?_assertEqual({{2013,3,6},{18,0,0}}, to_date("GMT","3/7/2013 12:00am +0600")), + ?_assertEqual({{2013,3,6},{12,0,0}}, to_date("CST","3/7/2013 12:00am +0600")), %% parsing, then reformatting the same time with a different timezone using the php "r" (rfc2822) ?_assertEqual("Thu, 07 Mar 2013 12:15:00 -0600", @@ -441,9 +453,10 @@ simple_test(_) -> ?_assertEqual(<<"2012-12-01 1:00pm">>, to_string(<<"Y-m-d g:ia">>,"EST","2012-12-01 12:00pm CST")), ?_assertEqual(<<"2012-12-01 1:00pm">>, to_string(<<"Y-m-d g:ia">>,"EST",<<"2012-12-01 12:00pm CST">>)), ?_assertEqual("2012-12-01 1:00pm", to_string("Y-m-d g:ia","EST",<<"2012-12-01 12:00pm CST">>)), + ?_assertEqual("2012-12-01 1:00pm", to_string("Y-m-d g:ia",<<"EST">>,<<"2012-12-01 12:00pm CST">>)), ?_assertEqual(to_unixtime("2012-01-01 12:00pm CST"), to_unixtime("2012-01-01 10:00am PST")), ?_assertEqual({{2012,12,31},{18,15,15}},to_date("Dec 31, 2012 6:15:15pm")), - ?_assertEqual({{2013,1,1},{0,15,15}},to_date("December 31, 2012 6:15:15pm CST","GMT")) + ?_assertEqual({{2013,1,1},{0,15,15}},to_date("GMT", "December 31, 2012 6:15:15pm CST")) ]}. parser_format_test(_) ->