From 52770185f96e9a9f607b4f36bba945fc591bf86e Mon Sep 17 00:00:00 2001 From: Matthias Wahl Date: Wed, 14 Oct 2015 16:13:42 +0200 Subject: [PATCH 01/15] fix date parse compatibility with ec_date as it turns out ec_dates datetime() type can also be {{Y,M,D},{H,M,S,Ms}} which was not yet covered --- src/qdate.erl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/qdate.erl b/src/qdate.erl index 0e6a804..d80529d 100644 --- a/src/qdate.erl +++ b/src/qdate.erl @@ -242,7 +242,9 @@ to_date(ToTZ, Disambiguate, RawDate) -> end, try raw_to_date(RawDate3) of D={{_,_,_},{_,_,_}} -> - date_tz_to_tz(D, Disambiguate, FromTZ, ToTZ) + date_tz_to_tz(D, Disambiguate, FromTZ, ToTZ); + {{Year, Month, Date},{Hour,Minute,Second,_Millis}} -> + date_tz_to_tz({{Year, Month, Date},{Hour,Minute,Second}}, Disambiguate, FromTZ, ToTZ) catch _:_ -> case raw_to_date(RawDate) of @@ -766,7 +768,9 @@ tz_tests(_) -> ?_assertEqual(ok, set_timezone("EST")), ?_assertEqual(555555555,to_unixtime("1987-08-10 00:59:15 GMT")), ?_assertEqual({555,555555,0},to_now("1987-08-10 00:59:15 GMT")), - ?_assertEqual(ok, set_timezone("GMT")) + ?_assertEqual(ok, set_timezone("GMT")), + ?_assertEqual({{1970, 1, 1}, {1, 0, 0}}, to_date("CET", "1970-01-01T00:00:00Z")) + ]}. From 8427b7bdc61d34dc4fa8dfc2a62eb2dcd2dd1724 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Thu, 5 Nov 2015 09:55:53 -0600 Subject: [PATCH 02/15] Update dependencies * Erlware Commons to non-crashing-with-rebar 0.15.0 * Erlang Localtime to base version, since it now has the necessary support for qdate functionality. --- rebar.config | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rebar.config b/rebar.config index 622fcf5..f4a731f 100644 --- a/rebar.config +++ b/rebar.config @@ -7,8 +7,12 @@ %% For rebar2 compat {deps, [ - {erlware_commons, ".*", {git, "git://github.com/erlware/erlware_commons.git", {branch, master}}}, - {erlang_localtime, ".*", {git, "git://github.com/choptastic/erlang_localtime.git", {branch, master}}} + %% This uses an older erlware_commons version so retain compatibility with + %% rebar2. v0.16.1 introduced a 'cf' dependency, which seems to cause + %% breakage. + {erlware_commons, ".*", {git, "git://github.com/erlware/erlware_commons.git", {tag, "v0.15.0"}}}, + + {erlang_localtime, ".*", {git, "git://github.com/dmitryme/erlang_localtime.git", {branch, master}}} ]}. %% for rebar3 From a504a6adfcbaa9f3d7f5052cc37b8b83522ab822 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Thu, 5 Nov 2015 11:31:38 -0600 Subject: [PATCH 03/15] Update rebar.config back to choptastic/erlang_localtime *temporary* until a commit is merged --- .gitignore | 1 + Makefile | 3 +++ rebar.config | 7 ++++--- src/qdate.app.src | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 49830e4..47010b0 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ deps/ ebin/ .eunit/ _build +rebar.lock diff --git a/Makefile b/Makefile index 2eb16b7..e94d5d0 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,9 @@ all: compile compile: $(REBAR) compile +update: + $(REBAR) update + test: compile $(REBAR) eunit diff --git a/rebar.config b/rebar.config index f4a731f..34c0671 100644 --- a/rebar.config +++ b/rebar.config @@ -1,7 +1,5 @@ %% -*- erlang -*- %% vim:ts=4 sw=4 et ft=erlang -{require_otp_vsn, "R13B04|R14|R15|R16|17|18"}. - {cover_enabled, true}. %% For rebar2 compat @@ -12,7 +10,10 @@ %% breakage. {erlware_commons, ".*", {git, "git://github.com/erlware/erlware_commons.git", {tag, "v0.15.0"}}}, - {erlang_localtime, ".*", {git, "git://github.com/dmitryme/erlang_localtime.git", {branch, master}}} + %% We'll temporarily still use choptastic/erlang_localtime until + %% https://github.com/dmitryme/erlang_localtime/pull/24 gets merged. Then we + %% can switch to the mainline repo + {erlang_localtime, ".*", {git, "git://github.com/choptastic/erlang_localtime.git", {branch, master}}} ]}. %% for rebar3 diff --git a/src/qdate.app.src b/src/qdate.app.src index 4c37fdd..1c522ce 100644 --- a/src/qdate.app.src +++ b/src/qdate.app.src @@ -1,7 +1,7 @@ {application, qdate, [ {description, "Simple Date and Timezone handling for Erlang"}, - {vsn, "0.4.1"}, + {vsn, "0.4.2"}, {registered, []}, {applications, [ kernel, From c4c20db81525aa15966f0df22ac3fc315b72c81a Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Thu, 5 Nov 2015 11:35:16 -0600 Subject: [PATCH 04/15] Update changelog --- CHANGELOG.markdown | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index 5bf09a6..54a2812 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -4,6 +4,11 @@ * Properly add dependent apps to .app.src (@Licenser) * Remove R14 from travis testing. +## 0.4.2 + +* Add partial support for `ec_date`'s 4-tuple subsecond accuracy time format. +* Fix `erlware_commons` dependency to a rebar2-compatible version. + ## 0.4.1 * Remove unnecessary `io:format` call. From b1387c08c01aa00a80c10331ce23ef0f78bc7c36 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Fri, 6 Nov 2015 17:03:16 -0600 Subject: [PATCH 05/15] Add range functions * Documentation needed --- src/qdate.erl | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/qdate.erl b/src/qdate.erl index d80529d..118efa3 100644 --- a/src/qdate.erl +++ b/src/qdate.erl @@ -47,6 +47,17 @@ add_date/2 ]). +-export([ + range/4, + range_seconds/3, + range_minutes/3, + range_hours/3, + range_days/3, + range_weeks/3, + range_months/3, + range_years/3 +]). + -export([ register_parser/2, register_parser/1, @@ -460,6 +471,77 @@ fmid({Y, M, D}) when D < 1 -> fmid(Date) -> Date. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Ranges %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +range(seconds, Interval, Start, Finish) -> + range_inner(fun add_seconds/2, Interval, Start, Finish); +range(minutes, Interval, Start, Finish) -> + range_inner(fun add_minutes/2, Interval, Start, Finish); +range(hours, Interval, Start, Finish) -> + range_inner(fun add_hours/2, Interval, Start, Finish); +range(days, Interval, Start, Finish) -> + range_inner(fun add_days/2, Interval, Start, Finish); +range(weeks, Interval, Start, Finish) -> + range_inner(fun add_weeks/2, Interval, Start, Finish); +range(months, Interval, Start, Finish) -> + range_inner(fun add_months/2, Interval, Start, Finish); +range(years, Interval, Start, Finish) -> + range_inner(fun add_years/2, Interval, Start, Finish). + +range_inner(IntervalFun, Interval, Start, Finish) when Interval > 0 -> + %% If Interval>0, then we're ascending, and we want to compare start/end + %% dates normally + CompareFun = fun(S, F) -> compare(S, F) end, + range_normalizer(IntervalFun, Interval, CompareFun, Start, Finish); +range_inner(IntervalFun, Interval, Start, Finish) when Interval < 0 -> + %% If Interval<0, then we're descending, and we want to compare start/end + %% dates backwards (we want to end when the Start Date is Lower than + %% Finish) + CompareFun = fun(S, F) -> compare(F, S) end, + range_normalizer(IntervalFun, Interval, CompareFun, Start, Finish); +range_inner(_, Interval, _, _) when Interval==0 -> + throw(interval_cannot_be_zero). + +range_normalizer(IntervalFun, Interval, CompareFun, Start0, Finish0) -> + %% Convert dates to unixtime for speed's sake + Start = to_unixtime(Start0), + Finish = to_unixtime(Finish0), + %% Prepare the incrementer, so we just need to pass the date to the incrementer. + Incrementer = fun(D) -> IntervalFun(Interval, D) end, + range_worker(Incrementer, CompareFun, Start, Finish). + +range_worker(Incrementer, CompareFun, Start, Finish) -> + case CompareFun(Start, Finish) of + 0 -> [Finish]; %% Equal, so we add our Finish value + 1 -> []; %% Start is after Finish, so we add nothing + -1 -> %% Start is before Finish, so we include it, and recurse + NextDay = Incrementer(Start), + [Start | range_worker(Incrementer, CompareFun, NextDay, Finish)] + end. + +range_seconds(Interval, Start, Finish) -> + range(seconds, Interval, Start, Finish). + +range_minutes(Interval, Start, Finish) -> + range(minutes, Interval, Start, Finish). + +range_hours(Interval, Start, Finish) -> + range(hours, Interval, Start, Finish). + +range_days(Interval, Start, Finish) -> + range(days, Interval, Start, Finish). + +range_weeks(Interval, Start, Finish) -> + range(weeks, Interval, Start, Finish). + +range_months(Interval, Start, Finish) -> + range(months, Interval, Start, Finish). + +range_years(Interval, Start, Finish) -> + range(years, Interval, Start, Finish). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%% Timezone Stuff %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% From 647e26db153ce71cbb0d2b999b3b26791470439d Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Fri, 6 Nov 2015 17:04:55 -0600 Subject: [PATCH 06/15] Update copyright notice on qdate.erl --- src/qdate.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qdate.erl b/src/qdate.erl index 118efa3..1d8838a 100644 --- a/src/qdate.erl +++ b/src/qdate.erl @@ -1,5 +1,5 @@ % vim: ts=4 sw=4 et -% Copyright (c) 2013 Jesse Gumm +% Copyright (c) 2013-2015 Jesse Gumm % See LICENSE for licensing information. % -module(qdate). From ef2075d4757f16b7dafe00253dfaee2d10566fa0 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Fri, 6 Nov 2015 17:06:30 -0600 Subject: [PATCH 07/15] Update changelog --- CHANGELOG.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index 54a2812..9c672e6 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -1,5 +1,6 @@ ## 0.5.0 (in development) +* Add range functions for getting a list of dates/times within a range. * Update to rebar3 and add hex compatability. (@Licenser) * Properly add dependent apps to .app.src (@Licenser) * Remove R14 from travis testing. From c685f4dc12eba720bf9ede3c6572fdac82f6a4e2 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Fri, 6 Nov 2015 17:26:26 -0600 Subject: [PATCH 08/15] Add range docs to readme --- README.markdown | 70 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index 5fcad6f..07560be 100644 --- a/README.markdown +++ b/README.markdown @@ -621,8 +621,6 @@ ok ## Date Arithmetic -(not fully tested yet, but will have full tests for 0.4.0) - The current implementation of qdate's date arithmetic returns Unixtimes. There are 8 main functions for date arithmetic: @@ -654,6 +652,74 @@ There are 7 other arithmetic functions that take a single argument, and these do + `add_months(Months)` + `add_years(Years)` +## Date and Time Ranges + +qdate provides a number of `range` functions that give applicable dates/times +within a start and end time. For example, "All days from 2015-01-01 to today", +"every 3rd month from 2000-01-01 to 2009-12-31", or "every 15 minutes from +midnight to 11:59pm on 2015-04-15". + +The functions are as follows: + + + `range_seconds(Interval, Start, End)` + + `range_minutes(Interval, Start, End)` + + `range_hours(Interval, Start, End)` + + `range_days(Interval, Start, End)` + + `range_weeks(Interval, Start, End)` + + `range_months(Interval, Start, End)` + + `range_years(Interval, Start, End)` + +Where `Interval` is the number of seconds/days/years/etc. + +So for example: + +```erlang +%% Get every 15th minute from "2015-04-15 12:00am to 2015-04-15 11:59am" +> qdate:range_minutes(15, "2015-04-15 12:00am", "2015-04-15 11:59am"). +[1429056000,1429056900,1429057800,1429058700,1429059600, + 1429060500,1429061400,1429062300,1429063200,1429064100, + 1429065000,1429065900,1429066800,1429067700,1429068600, + 1429069500,1429070400,1429071300,1429072200,1429073100, + 1429074000,1429074900,1429075800,1429076700,1429077600, + 1429078500,1429079400,1429080300,1429081200|...] + +%% Get every day of April, 2014 +> qdate:range_days(1, "2014-04-01", "2014-04-30"). +[1396310400,1396396800,1396483200,1396569600,1396656000, + 1396742400,1396828800,1396915200,1397001600,1397088000, + 1397174400,1397260800,1397347200,1397433600,1397520000, + 1397606400,1397692800,1397779200,1397865600,1397952000, + 1398038400,1398124800,1398211200,1398297600,1398384000, + 1398470400,1398556800,1398643200,1398729600|...] +``` + +Note, that the return value (just like qdate's arithmetic functions) is a list +of integers. These integers are unix timestamps and can be easily formatted +with qdate: + +```erlang +> Mins = qdate:range_minutes(15, "2015-04-15 12:00am", "2015-04-15 11:59am"), +> [qdate:to_string("Y-m-d h:ia", M) || M <- Mins]. +["2015-04-15 00:00am","2015-04-15 00:15am", + "2015-04-15 00:30am","2015-04-15 00:45am", + "2015-04-15 01:00am","2015-04-15 01:15am", + "2015-04-15 01:30am","2015-04-15 01:45am", + "2015-04-15 02:00am","2015-04-15 02:15am", + "2015-04-15 02:30am","2015-04-15 02:45am", + "2015-04-15 03:00am","2015-04-15 03:15am", + "2015-04-15 03:30am","2015-04-15 03:45am", + "2015-04-15 04:00am","2015-04-15 04:15am", + "2015-04-15 04:30am","2015-04-15 04:45am", + "2015-04-15 05:00am","2015-04-15 05:15am", + "2015-04-15 05:30am","2015-04-15 05:45am", + "2015-04-15 06:00am","2015-04-15 06:15am", + "2015-04-15 06:30am","2015-04-15 06:45am", + [...]|...] +``` + +Also note that the range functions are *inclusive*. + + ## Thanks A few shoutouts to [Dale Harvey](http://github.com/daleharvey) and the From faeadb732a70deccdaf7b797dc79eeaf8088d514 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Fri, 6 Nov 2015 17:28:27 -0600 Subject: [PATCH 09/15] Fix tab issue in readme --- README.markdown | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.markdown b/README.markdown index 07560be..851028d 100644 --- a/README.markdown +++ b/README.markdown @@ -625,17 +625,17 @@ The current implementation of qdate's date arithmetic returns Unixtimes. There are 8 main functions for date arithmetic: - + `add_seconds(Seconds, Date)` - + `add_minutes(Minutes, Date)` - + `add_hours(Hours, Date)` - + `add_days(Days, Date)` - + `add_weeks(Weeks, Date)` - + `add_months(Months, Date)` - + `add_years(Years, Date)` - + `add_date(DateToAdd, Date)` - `DateToAdd` is a shortcut way of adding - numerous options. For example. `qdate:add_date({{1, 2, -3}, {-500, 20, 0}})` - will add 1 year, add 2 months, subtract 3 days, subtract 500 hours, add 20 - minutes, and not make any changes to seconds. + + `add_seconds(Seconds, Date)` + + `add_minutes(Minutes, Date)` + + `add_hours(Hours, Date)` + + `add_days(Days, Date)` + + `add_weeks(Weeks, Date)` + + `add_months(Months, Date)` + + `add_years(Years, Date)` + + `add_date(DateToAdd, Date)` - `DateToAdd` is a shortcut way of adding + numerous options. For example. `qdate:add_date({{1, 2, -3}, {-500, 20, 0}})` + will add 1 year, add 2 months, subtract 3 days, subtract 500 hours, add 20 + minutes, and not make any changes to seconds. For the date arithmetic functions, `Date`, like all `qdate` functions, can be any format. From 792245bb264a93baca274560347dd6724aab5a61 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Fri, 6 Nov 2015 17:29:02 -0600 Subject: [PATCH 10/15] Fix tab issue (again) --- README.markdown | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.markdown b/README.markdown index 851028d..93e7bca 100644 --- a/README.markdown +++ b/README.markdown @@ -625,14 +625,14 @@ The current implementation of qdate's date arithmetic returns Unixtimes. There are 8 main functions for date arithmetic: - + `add_seconds(Seconds, Date)` - + `add_minutes(Minutes, Date)` - + `add_hours(Hours, Date)` - + `add_days(Days, Date)` - + `add_weeks(Weeks, Date)` - + `add_months(Months, Date)` - + `add_years(Years, Date)` - + `add_date(DateToAdd, Date)` - `DateToAdd` is a shortcut way of adding + + `add_seconds(Seconds, Date)` + + `add_minutes(Minutes, Date)` + + `add_hours(Hours, Date)` + + `add_days(Days, Date)` + + `add_weeks(Weeks, Date)` + + `add_months(Months, Date)` + + `add_years(Years, Date)` + + `add_date(DateToAdd, Date)` - `DateToAdd` is a shortcut way of adding numerous options. For example. `qdate:add_date({{1, 2, -3}, {-500, 20, 0}})` will add 1 year, add 2 months, subtract 3 days, subtract 500 hours, add 20 minutes, and not make any changes to seconds. From 6ca6037f291e91cb7a694a76c60bffd46532b5e7 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Sat, 7 Nov 2015 11:33:16 -0600 Subject: [PATCH 11/15] Add beginning_X functions with documentation * Still need tests --- README.markdown | 12 ++++++++++++ src/qdate.erl | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/README.markdown b/README.markdown index 93e7bca..5310710 100644 --- a/README.markdown +++ b/README.markdown @@ -619,6 +619,18 @@ ok %% that timezone to our intended timezone. ``` +## Date Truncation (Beginning of X) + +Sometimes you need to truncate a time (say, the beginning of the current month). + +This is abstracted to `beginning_X` functions, which return a date/time format with the dates and times truncated to the specified level. + + + `beginning_minute(Date)` + + `beginning_hour(Date)` + + `beginning_day(Date)` + + `beginning_month(Date)` + + `beginning_year(Date)` + ## Date Arithmetic The current implementation of qdate's date arithmetic returns Unixtimes. diff --git a/src/qdate.erl b/src/qdate.erl index 1d8838a..3311573 100644 --- a/src/qdate.erl +++ b/src/qdate.erl @@ -24,6 +24,15 @@ unixtime/0 ]). +-export([ + beginning_minute/1, + beginning_hour/1, + beginning_day/1, + %beginning_week/2, %% needs to be /2 because we also need to define what day is considered "beginning of week", since some calendars do sunday and some do monday. We'll hold off on implementation here + beginning_month/1, + beginning_year/1 +]). + -export([ compare/2, compare/3 @@ -324,6 +333,30 @@ to_now(Disamb, ToParse) -> end. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Beginning/Truncation %%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +beginning_minute(Date) -> + {{Y,M,D},{H,M,_}} = to_date(Date), + {{Y,M,D},{H,M,0}}. + +beginning_hour(Date) -> + {{Y,M,D},{H,_,_}} = to_date(Date), + {{Y,M,D},{H,0,0}}. + +beginning_day(Date) -> + {{Y,M,D},{_,_,_}} = to_date(Date), + {{Y,M,D},{0,0,0}}. + +beginning_month(Date) -> + {{Y,M,_},{_,_,_}} = to_date(Date), + {{Y,M,1},{0,0,0}}. + +beginning_year(Date) -> + {{Y,_,_},{_,_,_}} = to_date(Date), + {{Y,1,1},{0,0,0}}. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%% Comparisons %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% From d73a31e664bc8d13930909c3f098a113efe059f5 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Sat, 7 Nov 2015 11:39:24 -0600 Subject: [PATCH 12/15] Add beginning_X/0 variations --- README.markdown | 10 ++++++++-- src/qdate.erl | 22 +++++++++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/README.markdown b/README.markdown index 5310710..280b36f 100644 --- a/README.markdown +++ b/README.markdown @@ -621,9 +621,11 @@ ok ## Date Truncation (Beginning of X) -Sometimes you need to truncate a time (say, the beginning of the current month). +Sometimes you need to truncate a time (say, the beginning of the current +month). -This is abstracted to `beginning_X` functions, which return a date/time format with the dates and times truncated to the specified level. +This is abstracted to `beginning_X` functions, which return a date/time format +with the dates and times truncated to the specified level. + `beginning_minute(Date)` + `beginning_hour(Date)` @@ -631,6 +633,10 @@ This is abstracted to `beginning_X` functions, which return a date/time format w + `beginning_month(Date)` + `beginning_year(Date)` +There are also 0-arity versions of the above, in which `Date` is assumed to be +"right now". For example, calling `qdate:beginning_month()` would return +midnight on the first day of the current month. + ## Date Arithmetic The current implementation of qdate's date arithmetic returns Unixtimes. diff --git a/src/qdate.erl b/src/qdate.erl index 3311573..4ae135d 100644 --- a/src/qdate.erl +++ b/src/qdate.erl @@ -26,11 +26,16 @@ -export([ beginning_minute/1, + beginning_minute/0, beginning_hour/1, + beginning_hour/0, beginning_day/1, + beginning_day/0, %beginning_week/2, %% needs to be /2 because we also need to define what day is considered "beginning of week", since some calendars do sunday and some do monday. We'll hold off on implementation here beginning_month/1, - beginning_year/1 + beginning_month/0, + beginning_year/1, + beginning_year/0 ]). -export([ @@ -337,22 +342,37 @@ to_now(Disamb, ToParse) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%% Beginning/Truncation %%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +beginning_minute() -> + beginning_minute({date(),time()}). + beginning_minute(Date) -> {{Y,M,D},{H,M,_}} = to_date(Date), {{Y,M,D},{H,M,0}}. +beginning_hour() -> + beginning_hour({date(),time()}). + beginning_hour(Date) -> {{Y,M,D},{H,_,_}} = to_date(Date), {{Y,M,D},{H,0,0}}. +beginning_day() -> + beginning_day({date(),time()}). + beginning_day(Date) -> {{Y,M,D},{_,_,_}} = to_date(Date), {{Y,M,D},{0,0,0}}. +beginning_month() -> + beginning_month({date(),time()}). + beginning_month(Date) -> {{Y,M,_},{_,_,_}} = to_date(Date), {{Y,M,1},{0,0,0}}. +beginning_year() -> + beginning_year({date(),time()}). + beginning_year(Date) -> {{Y,_,_},{_,_,_}} = to_date(Date), {{Y,1,1},{0,0,0}}. From 37f8bf48e9b1363a52601de2570d497ec86d2f3d Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Sat, 7 Nov 2015 11:42:25 -0600 Subject: [PATCH 13/15] Update changelog --- CHANGELOG.markdown | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index 9c672e6..bc8c934 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -1,6 +1,9 @@ ## 0.5.0 (in development) -* Add range functions for getting a list of dates/times within a range. +* Add `range_X` functions for getting a list of dates/times within a range + (such as `range_day/3` to get a range of days between a start and end date. +* Add `beginning_X` functions to return the beginning of the provided precision + (minute, hour, day, month, or year) * Update to rebar3 and add hex compatability. (@Licenser) * Properly add dependent apps to .app.src (@Licenser) * Remove R14 from travis testing. From 63a34f1c682f5eb6b55764b958e2e7e5db087d66 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Thu, 28 Jan 2016 20:12:39 -0600 Subject: [PATCH 14/15] update readme --- README.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/README.markdown b/README.markdown index 280b36f..df35ae7 100644 --- a/README.markdown +++ b/README.markdown @@ -767,6 +767,7 @@ See [CHANGELOG.markdown](https://github.com/choptastic/qdate/blob/master/CHANGEL + Provide a sample qdate.config for users to see + Research the viability of [ezic](https://github.com/drfloob/ezic) for a timezone backend replacement for `erlang_localtime`. ++ Add age calculation stuff: `age_years(Date)`, `age_minutes(Date)`, etc. ## Conclusion From 0bf12290ecc4190bd3bfc16c75ffb174525d8059 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Thu, 28 Jan 2016 20:18:02 -0600 Subject: [PATCH 15/15] Update travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6a6becb..da6ba92 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,4 +8,4 @@ otp_release: - R15B02 - R15B01 - R15B -before_script: "sudo apt-get --yes --force-yes install libpam0g-dev" +before_script: "sudo apt-get --yes --force-yes install libpam-runtime"