Add relative date/time parsing parser.
This commit is contained in:
parent
5d73286e92
commit
41b313d425
1 changed files with 94 additions and 1 deletions
|
@ -61,6 +61,8 @@
|
||||||
add_months/1,
|
add_months/1,
|
||||||
add_years/2,
|
add_years/2,
|
||||||
add_years/1,
|
add_years/1,
|
||||||
|
add_unit/2,
|
||||||
|
add_unit/3,
|
||||||
add_date/2
|
add_date/2
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
@ -94,6 +96,9 @@
|
||||||
clear_timezone/1
|
clear_timezone/1
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
-export([
|
||||||
|
parse_relative/1
|
||||||
|
]).
|
||||||
|
|
||||||
%% Exported for API compatibility with ec_date
|
%% Exported for API compatibility with ec_date
|
||||||
-export([
|
-export([
|
||||||
|
@ -309,7 +314,8 @@ to_unixtime(Date) ->
|
||||||
|
|
||||||
to_unixtime(_, Unixtime) when is_integer(Unixtime) ->
|
to_unixtime(_, Unixtime) when is_integer(Unixtime) ->
|
||||||
Unixtime;
|
Unixtime;
|
||||||
to_unixtime(_, {MegaSecs,Secs,_}) ->
|
|
||||||
|
to_unixtime(_, {MegaSecs,Secs,_}) when is_integer(MegaSecs), is_integer(Secs) ->
|
||||||
MegaSecs*1000000 + Secs;
|
MegaSecs*1000000 + Secs;
|
||||||
to_unixtime(Disamb, ToParse) ->
|
to_unixtime(Disamb, ToParse) ->
|
||||||
%% We want to treat all unixtimes as GMT
|
%% We want to treat all unixtimes as GMT
|
||||||
|
@ -483,6 +489,39 @@ add_years(Years, Date) ->
|
||||||
add_years(Years) ->
|
add_years(Years) ->
|
||||||
add_years(Years, os:timestamp()).
|
add_years(Years, os:timestamp()).
|
||||||
|
|
||||||
|
add_unit(second, Value, Date) ->
|
||||||
|
add_unit(seconds, Value, Date);
|
||||||
|
add_unit(seconds, Value, Date) ->
|
||||||
|
add_seconds(Value, Date);
|
||||||
|
add_unit(minute, Value, Date) ->
|
||||||
|
add_unit(minutes, Value, Date);
|
||||||
|
add_unit(minutes, Value, Date) ->
|
||||||
|
add_minutes(Value, Date);
|
||||||
|
add_unit(hour, Value, Date) ->
|
||||||
|
add_unit(hours, Value, Date);
|
||||||
|
add_unit(hours, Value, Date) ->
|
||||||
|
add_hours(Value, Date);
|
||||||
|
add_unit(day, Value, Date) ->
|
||||||
|
add_unit(days, Value, Date);
|
||||||
|
add_unit(days, Value, Date) ->
|
||||||
|
add_days(Value, Date);
|
||||||
|
add_unit(week, Value, Date) ->
|
||||||
|
add_unit(weeks, Value, Date);
|
||||||
|
add_unit(weeks, Value, Date) ->
|
||||||
|
add_weeks(Value, Date);
|
||||||
|
add_unit(month, Value, Date) ->
|
||||||
|
add_unit(months, Value, Date);
|
||||||
|
add_unit(months, Value, Date) ->
|
||||||
|
add_months(Value, Date);
|
||||||
|
add_unit(year, Value, Date) ->
|
||||||
|
add_unit(years, Value, Date);
|
||||||
|
add_unit(years, Value, Date) ->
|
||||||
|
add_years(Value, Date).
|
||||||
|
|
||||||
|
add_unit(Unit, Value) ->
|
||||||
|
add_unit(Unit, Value, os:timestamp()).
|
||||||
|
|
||||||
|
|
||||||
add_date({{AddY, AddM, AddD}, {AddH, AddI, AddS}}, Date) ->
|
add_date({{AddY, AddM, AddD}, {AddH, AddI, AddS}}, Date) ->
|
||||||
{{Y, M, D}, {H, I, S}} = to_date(Date),
|
{{Y, M, D}, {H, I, S}} = to_date(Date),
|
||||||
Date1 = fix_maybe_improper_date({{Y+AddY, M+AddM, D+AddD}, {H, I, S}}),
|
Date1 = fix_maybe_improper_date({{Y+AddY, M+AddM, D+AddD}, {H, I, S}}),
|
||||||
|
@ -610,6 +649,58 @@ range_years(Interval, Start, Finish) ->
|
||||||
range(years, Interval, Start, Finish).
|
range(years, Interval, Start, Finish).
|
||||||
|
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%% Relative Date Parsing %%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
parse_relative({relative, Date, Relation}) when is_atom(Relation) ->
|
||||||
|
parse_relative({relative, Date, atom_to_list(Relation)});
|
||||||
|
parse_relative({relative, Date, Relation}) ->
|
||||||
|
{OpStr, NumStr, UnitStr} = parse_actual_relation(Relation),
|
||||||
|
{Num, Unit} = normalize_relative_matches(OpStr, NumStr, UnitStr),
|
||||||
|
add_unit(Unit, Num, Date);
|
||||||
|
parse_relative(now) ->
|
||||||
|
unixtime();
|
||||||
|
parse_relative("now") ->
|
||||||
|
unixtime();
|
||||||
|
parse_relative(<<"now">>) ->
|
||||||
|
unixtime();
|
||||||
|
parse_relative(Relation) ->
|
||||||
|
parse_relative({relative, unixtime(), Relation}).
|
||||||
|
|
||||||
|
|
||||||
|
%% I would do this function recursively, but the return order of arguments
|
||||||
|
%% inconsistent, so I just leave it like this. It's a little nasty to have the
|
||||||
|
%% nested case expressions, but I can deal with it.
|
||||||
|
parse_actual_relation(Relation) ->
|
||||||
|
PrefixRE = "^(\\-|\\+|in)\\s?(\\d+) (second|minute|hour|day|week|month|year)s?$",
|
||||||
|
SuffixRE = "^(\\d+) (second|minute|hour|day|week|month|year)s\\s?(ago|from now)?$",
|
||||||
|
case re:run(Relation, PrefixRE, [{capture, all_but_first, list}]) of
|
||||||
|
nomatch ->
|
||||||
|
case re:run(Relation, SuffixRE, [{capture, all_but_first, list}]) of
|
||||||
|
nomatch -> undefined;
|
||||||
|
{match, [NumStr, UnitStr, OpStr]} ->
|
||||||
|
{OpStr, NumStr, UnitStr}
|
||||||
|
end;
|
||||||
|
{match, [OpStr, NumStr, UnitStr]} ->
|
||||||
|
{OpStr, NumStr, UnitStr}
|
||||||
|
end.
|
||||||
|
|
||||||
|
normalize_relative_matches(OpStr, NumStr, UnitStr) ->
|
||||||
|
Op = normalize_relative_op(OpStr),
|
||||||
|
Num = list_to_integer(Op ++ NumStr),
|
||||||
|
Unit = list_to_existing_atom(UnitStr),
|
||||||
|
{Num, Unit}.
|
||||||
|
|
||||||
|
normalize_relative_op(Op) ->
|
||||||
|
case Op of
|
||||||
|
"+" -> "+";
|
||||||
|
"-" -> "-";
|
||||||
|
"ago" -> "-";
|
||||||
|
"from now" -> "+";
|
||||||
|
"in" -> "+"
|
||||||
|
end.
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Timezone Stuff %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Timezone Stuff %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -637,6 +728,8 @@ extract_timezone(DateString) when is_list(DateString) ->
|
||||||
end;
|
end;
|
||||||
extract_timezone(Date={{_,_,_},{_,_,_}}) ->
|
extract_timezone(Date={{_,_,_},{_,_,_}}) ->
|
||||||
{Date, ?DETERMINE_TZ};
|
{Date, ?DETERMINE_TZ};
|
||||||
|
extract_timezone(Rel={relative, _, _}) ->
|
||||||
|
{Rel, "GMT"};
|
||||||
extract_timezone(Now={_,_,_}) ->
|
extract_timezone(Now={_,_,_}) ->
|
||||||
{Now, "GMT"};
|
{Now, "GMT"};
|
||||||
extract_timezone({MiscDate,TZ}) ->
|
extract_timezone({MiscDate,TZ}) ->
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue