From 0a7d808290893e7bc5d009902c4c453cf64eea4a Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Fri, 20 Nov 2020 14:14:25 -0600 Subject: [PATCH] Add age functions --- CHANGELOG.markdown | 4 ++++ README.markdown | 11 ++++++++- src/qdate.erl | 60 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index 37f504a..2c16875 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -1,3 +1,7 @@ +## 0.6.0 (in development) + +* Add `age` and `age_days` functions + ## 0.5.0 * Add `range_X` functions for getting a list of dates/times within a range diff --git a/README.markdown b/README.markdown index 25b9e56..d12f64d 100644 --- a/README.markdown +++ b/README.markdown @@ -845,6 +845,16 @@ with qdate: Also note that the range functions are *inclusive*. + +## Age Comparison + +There are two main comparisons right now, age in years, and age in days. + + + `age(Date)` - Number of years since `Date` + + `age(FromDate, ToDate)` - Number of years between `FromDate` to `ToDate` + + `age_days(Date)` - Number of full days since `Date` (for example from `2pm` yesterday to `1:59pm` today is still 0. + + `age_days(FromDate, ToDate)` - Number of full days between `FromDate` and `ToDate`. + ## Configuration Sample There is a sample configuration file can be found in the root of the qdate @@ -879,7 +889,6 @@ See [CHANGELOG.markdown](https://github.com/choptastic/qdate/blob/master/CHANGEL + Add `-spec` and `-type` info for dialyzer + 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 diff --git a/src/qdate.erl b/src/qdate.erl index e81061e..a1608c5 100644 --- a/src/qdate.erl +++ b/src/qdate.erl @@ -101,6 +101,13 @@ range_years/3 ]). +-export([ + age/1, + age/2, + age_days/1, + age_days/2 +]). + -export([ register_parser/2, register_parser/1, @@ -768,6 +775,42 @@ fmid({Y, M, D}) when D < 1 -> fmid(Date) -> Date. +age(Birth) -> + age(Birth, os:timestamp()). + +age(Birth, Now) -> + %% B=Birth + {{BY, BM, BD}, _} = to_date(Birth), + %% C=Current + {{CY, CM, CD}, _} = to_date(Now), + if + (CM > BM); + (CM == BM andalso CD >= BD) + -> CY - BY; + true -> + (CY - BY) - 1 + end. + +age_days(Birth) -> + age_days(Birth, os:timestamp()). + +age_days(Birth, Now) -> + case {to_date(Birth), to_date(Now)} of + {{_SameDay, _}, {_SameDay, _}} -> + 0; + {{BirthDate, BirthTime}, {NowDate, NowTime}} -> + BirthDays = calendar:date_to_gregorian_days(BirthDate), + NowDays = calendar:date_to_gregorian_days(NowDate), + DiffDays = NowDays - BirthDays, + if + NowTime >= BirthTime -> + DiffDays; + true -> + DiffDays-1 + end + end. + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%% Ranges %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1340,7 +1383,22 @@ arith_tests(_) -> ?_assertEqual({{2017,1,3},{0,0,0}}, beginning_week(2, {{2017,1,4},{0,0,0}})), ?_assertEqual({{2016,12,29},{0,0,0}}, beginning_week(4, {{2017,1,4},{0,0,0}})), ?_assertEqual({{2016,12,31},{0,0,0}}, beginning_week(6, {{2017,1,6},{0,0,0}})), - ?_assertEqual({{2017,1,1},{0,0,0}}, beginning_week(7, {{2017,1,6},{0,0,0}})) + ?_assertEqual({{2017,1,1},{0,0,0}}, beginning_week(7, {{2017,1,6},{0,0,0}})), + + ?_assertEqual(0, age("1981-01-15", "1981-12-31")), + ?_assertEqual(39, age("1981-01-15", "2020-01-15")), + ?_assertEqual(39, age("1981-01-15", "2020-01-15 12am")), + ?_assertEqual(38, age("1981-01-15", "2020-01-14")), + ?_assertEqual(38, age("1981-01-15", "2020-01-14 11:59pm")), + + %% checking pre-unix-epoch + ?_assertEqual(100, age("1901-01-01","2001-01-01")), + ?_assertEqual(20, age("1900-01-01", "1920-01-01")), + + ?_assertEqual(0, age_days("2020-11-20 12am","2020-11-20 11:59:59pm")), + ?_assertEqual(1, age_days("2020-11-19 11:59:59pm","2020-11-20 11:59:59pm")), + ?_assertEqual(7, age_days("2020-11-20","2020-11-27")), + ?_assertEqual(7, age_days("2020-11-27","2020-12-04")) ]}.