consolidated logic, added date normalization and overlap methods.
This commit is contained in:
@@ -52,7 +52,7 @@ flatten(Zones, Rules) ->
|
||||
SortedZoneSet= lists:sort(fun zone_sorter/2, ZoneSet),
|
||||
|
||||
flatten_set(SortedZoneSet, NeededRules),
|
||||
?debug("Sorted Zones: ~p", [SortedZoneSet]),
|
||||
% ?debug("Sorted Zones: ~p", [SortedZoneSet]),
|
||||
|
||||
flatten(RestZones, Rules).
|
||||
|
||||
@@ -60,7 +60,7 @@ flatten(Zones, Rules) ->
|
||||
|
||||
|
||||
zone_sorter(Z1=#zone{until=U1},#zone{until=U2}) ->
|
||||
ezic_record:compare_datetimes(U1, U2).
|
||||
ezic_date:compare_datetimes(U1, U2).
|
||||
|
||||
|
||||
%% case (D1 =< D2) of
|
||||
@@ -86,14 +86,11 @@ make_rule_zone_filter(#zone{rule=Rule}) ->
|
||||
fun(#rule{name=Rule})-> true; (_)->false end.
|
||||
|
||||
|
||||
% accepts a rule, and returns true if it exists between the two years given
|
||||
make_rule_time_filter(D1, D2) ->
|
||||
fun(#rule{from=F, to=T}) ->
|
||||
GoodFrom= ezic_record:compare_datetimes(D1, F) =:= true
|
||||
andalso ezic_record:compare_datetimes(F, D2) =:= true,
|
||||
GoodTo= ezic_record:compare_datetimes(D1, T) =:= true
|
||||
andalso ezic_record:compare_datetimes(T, D2) =:= true,
|
||||
GoodFrom orelse GoodTo
|
||||
end.
|
||||
ezic_date:overlap({D1,D2}, {F,T})
|
||||
end.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -10,13 +10,14 @@
|
||||
|
||||
-export([for/2]).
|
||||
-export([month_to_num/1, day_to_num/1]).
|
||||
-export([compare_times/2, compare_dates/2, compare_datetimes/2]).
|
||||
-export([compare_times/2, compare_datetimes/2, normalize/1, overlap/2]).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
% returns the concrete date tuple for a given rule and year
|
||||
% returns the concrete date tuple for a given rule and year, irrespective of zone
|
||||
% e.g. -> {Y,M,D}
|
||||
for(#rule{in=M, on={last, D}}, Y) ->
|
||||
last_day_of(D, Y,M);
|
||||
for(#rule{in=M, on=#tzon{day=Day, filter=Filter}}, Y) ->
|
||||
@@ -29,6 +30,7 @@ last_day_of(Day, Y,M) ->
|
||||
previous_day(Day, {Y,M,LastDay}).
|
||||
|
||||
|
||||
% returns a date tuple {Y,M,D} representing the first available date, given the filter
|
||||
first_day_limited(Day, {geq, N}, Y,M) ->
|
||||
next_day(Day, {Y,M,N});
|
||||
first_day_limited(Day, {leq, N}, Y,M) ->
|
||||
@@ -99,51 +101,88 @@ day_to_num(_) -> -1.
|
||||
|
||||
|
||||
|
||||
% returns true if A =< B, false otherwise
|
||||
compare_datetimes(_, current) ->
|
||||
compare_datetimes(DT1, DT2) ->
|
||||
NDT1= normalize(DT1),
|
||||
NDT2= normalize(DT2),
|
||||
compare_datetimes_normal(NDT1, NDT2).
|
||||
|
||||
|
||||
compare_datetimes_normal(current, _) -> false;
|
||||
compare_datetimes_normal(_,current) -> true;
|
||||
|
||||
compare_datetimes_normal({D1, T1}, {D2, T2}) when D1 < D2 ->
|
||||
true;
|
||||
compare_datetimes(current,_) ->
|
||||
compare_datetimes_normal({D1, T1}, {D2, T2}) when D1 > D2 ->
|
||||
false;
|
||||
|
||||
compare_datetimes(D1={_,_,_}, D2={_,_,_}) ->
|
||||
compare_dates(D1, D2);
|
||||
|
||||
compare_datetimes(D1={_,_,_}, DT2={_, #tztime{}}) ->
|
||||
compare_datetimes({D1, #tztime{}}, DT2);
|
||||
|
||||
compare_datetimes(DT1={_, #tztime{}}, D2={_,_,_}) ->
|
||||
compare_datetimes(DT1, {D2, #tztime{}});
|
||||
|
||||
compare_datetimes({D1, T1}, {D2, T2}) ->
|
||||
case compare_dates(D1, D2) of
|
||||
false -> % D1 > D2
|
||||
false;
|
||||
true -> % D1 =< D2
|
||||
case D1 =:= D2 of
|
||||
false -> % D1 < D2
|
||||
true;
|
||||
true -> % D1 = D2
|
||||
compare_times(T1, T2)
|
||||
end
|
||||
end.
|
||||
compare_datetimes_normal({_, T1}, {_, T2}) ->
|
||||
compare_times(T1, T2).
|
||||
|
||||
|
||||
compare_dates(D1={_,_,_}, D2={_,_,_}) ->
|
||||
D1 =< D2.
|
||||
|
||||
|
||||
compare_times(TZ1=#tztime{}, TZ2=#tztime{}) ->
|
||||
{NT1, NT2} = time_normalize(TZ1, TZ2),
|
||||
{NT1, NT2} = time_equalize(TZ1, TZ2),
|
||||
NT1 =< NT2;
|
||||
compare_times(T1, T2) ->
|
||||
T1 =< T2.
|
||||
compare_times(Tz1, Tz2) ->
|
||||
erlang:error(wtf_not_done, [Tz1, Tz2]).
|
||||
|
||||
|
||||
|
||||
time_normalize(#tztime{time=T1, flag=F1}, #tztime{time=T2, flag=F2}) when F1=:=F2 ->
|
||||
time_equalize(#tztime{time=T1, flag=F1}, #tztime{time=T2, flag=F2}) when F1=:=F2 ->
|
||||
{T1, T2};
|
||||
time_normalize(T1, T2) ->
|
||||
time_equalize(T1, T2) ->
|
||||
%@todo this may be difficult. gotta do it!
|
||||
erlang:error(wtf_not_done, T1, T2).
|
||||
|
||||
|
||||
|
||||
normalize(current) -> current;
|
||||
normalize(only) -> only;
|
||||
|
||||
normalize(Y) when is_integer(Y) ->
|
||||
{{Y,1,1}, #tztime{}};
|
||||
normalize(Date={_,_,D}) when is_integer(D) ->
|
||||
{Date, #tztime{}};
|
||||
normalize({Y,M,{last, D}}) ->
|
||||
Date=last_day_of(D, Y,M),
|
||||
{Date, #tztime{}};
|
||||
|
||||
|
||||
normalize({Date={Y,M,D}, Tz=#tztime{}}) when is_integer(D) ->
|
||||
{Date, Tz};
|
||||
normalize({{Y,M,TzOn=#tzon{day=Day, filter=Filter}}, Tz=#tztime{}}) ->
|
||||
Date= first_day_limited(Day, Filter, Y,M),
|
||||
{Date, Tz};
|
||||
normalize({{Y,M,{last, D}}, Tz=#tztime{}}) ->
|
||||
Date=last_day_of(D, Y,M),
|
||||
{Date, Tz};
|
||||
normalize(X) ->
|
||||
?debug("normalize: ~p", [X]),
|
||||
erlang:error(wtf_not_done, X).
|
||||
|
||||
|
||||
|
||||
|
||||
overlap({D1s,D1e}, {D2s,D2e}) ->
|
||||
D1sN= normalize(D1s),
|
||||
D1eN= normalize(D1e),
|
||||
D2sN= normalize(D2s),
|
||||
D2eN= normalize(D2e),
|
||||
dates_overlap_normal({D1sN,D1eN}, {D2sN,D2eN}).
|
||||
|
||||
|
||||
dates_overlap_normal({D1s,D1e}, {D2s,D2e}) ->
|
||||
date_between_normal(D1s, {D2s,D2e})
|
||||
orelse date_between_normal(D1e, {D2s,D2e}).
|
||||
|
||||
|
||||
date_between_normal(only, _) -> false;
|
||||
date_between_normal(current, {_, current}) -> true;
|
||||
date_between_normal(current, {_, End}) when End =/= current -> false;
|
||||
date_between_normal(D1, {D2, only}) ->
|
||||
{{Y1,_,_},_}=D1,
|
||||
{{Y2,_,_},_}=D2,
|
||||
Y1 =:= Y2;
|
||||
date_between_normal(D1, {D2s, D2e}) ->
|
||||
compare_datetimes_normal(D2s, D1)
|
||||
andalso compare_datetimes_normal(D1, D2e).
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user