flattening algorithm needs to be reworked.
also, datetime methods aren't consistent in their naming and return values.
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
-module(ezic_flatten).
|
||||
-include("include/ezic.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
|
||||
-define(FLAT(W,S,U), #flatzone{wall_from=W, std_from=S, utc_from=U}).
|
||||
-define(ENDFLAT(F,W,S,U), F#flatzone{wall_to=W, std_to=S, utc_to=U}).
|
||||
@@ -19,7 +21,6 @@ flatten() ->
|
||||
not_done.
|
||||
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% PRIVATE
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
@@ -29,43 +30,11 @@ flatten() ->
|
||||
flatten_zones(Zones) ->
|
||||
flatten_zones(Zones, []).
|
||||
|
||||
|
||||
|
||||
make_next_flat(#flatzone{wall_to=W, std_to=S, utc_to=U, offset=O}) ->
|
||||
make_next_flat({W,S,U}, O);
|
||||
make_next_flat(EndTimes) ->
|
||||
make_next_flat(EndTimes, undefined).
|
||||
|
||||
|
||||
make_next_flat({W,S,U}, O) ->
|
||||
FW= ezic_date:add_seconds(W,1),
|
||||
FS= ezic_date:add_seconds(S,1),
|
||||
FU= ezic_date:add_seconds(U,1),
|
||||
Flat= ?FLAT(FW, FS, FU),
|
||||
Flat#flatzone{offset=O}.
|
||||
|
||||
|
||||
|
||||
end_flat(Flat=#flatzone{}, {W,S,U}) ->
|
||||
?ENDFLAT(Flat,W,S,U).
|
||||
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% INTERNAL
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
|
||||
|
||||
|
||||
flatten_zones([], Flats) ->
|
||||
Flats;
|
||||
flatten_zones([Z1|_]= AllZones, Flats) ->
|
||||
{CurrentZones, RestZones}= ezic_zone:split_by_name(Z1, AllZones),
|
||||
|
||||
SortedZones= lists:sort(fun ezic_zone:sort_ascending/2, CurrentZones),
|
||||
NewFlats= lists:merge(Flats, flatten_zone_set(SortedZones)),
|
||||
|
||||
NewFlats= lists:merge(Flats, flatten_zone_set(CurrentZones)),
|
||||
flatten_zones(RestZones, NewFlats).
|
||||
|
||||
|
||||
@@ -88,7 +57,12 @@ flatten_zone_set(Zones) ->
|
||||
% assumes a new zone every time it is called
|
||||
flatten_zone_set(_, [], Flats) ->
|
||||
Flats;
|
||||
flatten_zone_set(FromTimeStub=#flatzone{utc_from=UTCFrom, dstoffset=DSTOffset}, [Z1=#zone{rule=RuleName, until=UntilTime, gmtoff=Offset} | _RestZones], _Flats) ->
|
||||
flatten_zone_set(FromTimeStub=#flatzone{utc_from=UTCFrom, dstoffset=DSTOffset}
|
||||
, Zones %[Z1=#zone{rule=RuleName, until=UntilTime, gmtoff=Offset} | _RestZones],
|
||||
, Flats) ->
|
||||
|
||||
{Zone, RestZones}= ezic_zone:next(Zones, UTCFrom, DSTOffset),
|
||||
#zone{rule=RuleName, until=UntilTime, gmtoff=Offset}=Zone,
|
||||
|
||||
%% we have a flatzone with start times, we populate the base offset
|
||||
FromTime= FromTimeStub#flatzone{offset=Offset},
|
||||
@@ -97,7 +71,10 @@ flatten_zone_set(FromTimeStub=#flatzone{utc_from=UTCFrom, dstoffset=DSTOffset},
|
||||
|
||||
%% we gather all rules that _may_ apply (same year)
|
||||
Rules= ezic_db:rules(RuleName),
|
||||
RuleDates= lists:foldl(
|
||||
|
||||
%% and add normalized (inaccurate) dates for sorting purposes
|
||||
%% note this may be empty
|
||||
RulesWithDates= lists:foldl(
|
||||
fun(R, Acc)->
|
||||
case ezic_rule:project_next(R, Offset, DSTOffset, UTCFrom) of
|
||||
none -> Acc;
|
||||
@@ -105,11 +82,33 @@ flatten_zone_set(FromTimeStub=#flatzone{utc_from=UTCFrom, dstoffset=DSTOffset},
|
||||
end
|
||||
end
|
||||
,[], Rules),
|
||||
AllDates= [{ezic_zone:project_end(Z1, DSTOffset), Z1} | RuleDates],
|
||||
|
||||
|
||||
%% tack on the zone w/ date, in case it ends first
|
||||
ZoneWithDate= {ezic_zone:project_end_utc(Zone, DSTOffset), Zone},
|
||||
|
||||
[NextEventWithDate | RestWithDates]= lists:sort(RulesAndZoneWithDates),
|
||||
?debugVal(NextEventWithDate),
|
||||
?debugVal(RestWithDates),
|
||||
|
||||
{_,NextEvent}= NextEventWithDate,
|
||||
{EndFlat, NextFlat}= finish_and_start_flat(FromTime, NextEvent, Offset, DSTOffset),
|
||||
NewFlats= [EndFlat | Flats],
|
||||
|
||||
RestZones= [Z || {_,Z} <- RestWithDates],
|
||||
|
||||
flatten_zone_set(NextFlat, RestZones, NewFlats).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
finish_and_start_flat(Flat=#flatzone{}, Zone=#zone{}, _Offset, DSTOffset) ->
|
||||
NextStart= {WT, ST, UT}= ezic_zone:project_end(Zone, DSTOffset),
|
||||
{MWT, MST, MUT}= ezic_date:m1s(NextStart),
|
||||
EndFlat= ?ENDFLAT(Flat, MWT, MST, MUT),
|
||||
NextFlat= ?FLAT(WT, ST, UT),
|
||||
{EndFlat, NextFlat};
|
||||
|
||||
finish_and_start_flat(Flat=#flatzone{utc_from=UTCFrom}, Rule=#rule{}, Offset, DSTOffset) ->
|
||||
not_done.
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user