Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 3f438e66e0
Fetching contributors…

Cannot retrieve contributors at this time

120 lines (81 sloc) 3.698 kb
-module(ezic_rule).
-include("include/ezic.hrl").
-export([parse/1]).
-export([project_next/4]).
parse([Name,FromS,ToS,_Type,InS,OnS,AtS,SaveS,Letters]) ->
From= ezic_parse:year(FromS),
To= ezic_parse:year(ToS),
% @todo handle year types
In= ezic_date:month_to_num(InS),
On= ezic_parse:day_pattern(OnS),
At= ezic_parse:time(AtS),
Save= ezic_parse:time_val(SaveS),
Rule= #rule{name=Name, from=From, to=To, type=not_done,
in=In, on=On, at=At, save=Save, letters=Letters},
{ok, Rule}.
% returns the projected date of the next "rule event" in UTC time,
% after the given UTCDatetime, with the given the zone Offset and current DST offset.
project_next(Rule=#rule{from=RFrom}, Offset, DSTOffset, minimum) ->
ezic_date:for_rule_utc(Rule, Offset, DSTOffset, RFrom);
project_next(Rule=#rule{}, Offset, DSTOff, UTCAfter={{AY,_,_},_}) ->
YearRange= years(Rule),
GoodYears= years_after(AY, YearRange),
project_next2(Rule, Offset, UTCAfter, DSTOff, GoodYears).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% PRIVATE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% returns the range of years a rule existed for, normalized for calculations.
years(#rule{from=From, to=only}) ->
{From,From};
years(#rule{from=From, to=X}) when X=:=max; X=:=maximum->
{From,X};
years(#rule{from=From, to=To}) when From =< To, is_integer(From), is_integer(To) ->
{From, To};
years(#rule{from=From, to=To}) ->
erlang:error(bad_year_range, [From, To]).
%% returns the range of years that are greater than OR equal to Y.
%% calculation stops after a fixed year, configurable above.
years_after(Y, {F,M}) when M=:=max; M=:=maximum ->
{erlang:max(Y,F), M};
years_after(Y, {From, To}) when Y > To ->
none;
years_after(Y, {From, To}) ->
{erlang:max(Y,From), To}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% INTERNAL
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
project_next2(_,_,_,_,none) ->
none;
project_next2(Rule, Offset, UTCAfter, DSTOffset, Years={FromYear, _}) ->
RuleDate= ezic_date:for_rule_utc(Rule, Offset, DSTOffset, FromYear),
case ezic_date:compare(UTCAfter, RuleDate) andalso (not ezic_date:equal(UTCAfter, RuleDate)) of
true -> RuleDate;
false ->
RestYears= years_after(FromYear+1, Years),
project_next2(Rule, Offset, UTCAfter, DSTOffset, RestYears)
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Tests of Private Methods
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
years_test_() ->
[
?_assertEqual({1952,1952}, years(#rule{from=1952,to=only}))
, ?_assertEqual({1952,1953}, years(#rule{from=1952,to=1953}))
, ?_assertEqual({1952,1955}, years(#rule{from=1952,to=1955}))
, ?_assertEqual({1952,max}, years(#rule{from=1952,to=max}))
, ?_assertEqual({1952,maximum}, years(#rule{from=1952,to=maximum}))
, ?_assertError(bad_year_range, years(#rule{from=1955,to=1952}))
].
% @todo type checking. lack of types worries me sometimes :(
years_after_test_() ->
[
?_assertEqual({2010,2010}, years_after(2010, {2010,2010}))
, ?_assertEqual({2010,2011}, years_after(2010, {2010,2011}))
, ?_assertEqual({2011,2011}, years_after(2011, {2010,2011}))
, ?_assertEqual({2011,max}, years_after(2011, {2010,max}))
, ?_assertEqual({2010,max}, years_after(2009, {2010,max}))
, ?_assertEqual(none, years_after(2012, {2010,2011}))
].
-endif.
Jump to Line
Something went wrong with that request. Please try again.