Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

removed all warnings. fixed bug in ezic_zone:next/3. unit tests for e…

…zic_zone:next/3

ezic_zone:next/3 was not filtering the Zones to only those after UTCFrom. This may have caused an endless loop, always returning the earliest zone regardless of the progress of time. I wont know; I caught it rather early.
  • Loading branch information...
commit c976e63349e12d827ca492fbdefe4b71270b6064 1 parent 1520c63
@drfloob authored
View
1  Makefile
@@ -23,6 +23,7 @@ compile :
clean :
-@rm ebin/*
+ -@rm erl_crash.dump
run :
View
14 include/ezic.hrl
@@ -19,17 +19,3 @@
% a flattened zone record, giving specific information for a specific time range.
-record(flatzone, {tzname, wall_from, wall_to, std_from, std_to, utc_from, utc_to, offset, dstoffset={0,0,0}}).
-
-
-
--ifdef(debug).
--define(debug(F,X), io:format("{~p:~p} - " ++ F ++ "~n", [?MODULE, ?LINE] ++ X)).
--define(debug(F), io:format("{~p:~p} - ~p~n", [?MODULE, ?LINE, F])).
--else.
--define(debug(F,X), void).
--define(debug(F), void).
--endif.
-
-
-
-
View
5 src/ezic_date.erl
@@ -23,6 +23,7 @@
, add_offset/2
, all_times/3
, m1s/1
+ , m1s/3
% comparisons
, compare/2
@@ -46,7 +47,7 @@ normalize(Y) when is_integer(Y) ->
normalize(Date={Y,M,D})
when is_integer(Y), is_integer(M), is_integer(D) ->
{Date, #tztime{}};
-normalize(R={{Y,M,D}, #tztime{}}) ->
+normalize(R={{_,_,_}, #tztime{}}) ->
R.
@@ -104,7 +105,7 @@ add_seconds(Datetime, Seconds) ->
calendar:datetime_to_gregorian_seconds(Datetime) + Seconds
)
catch
- error:Reason -> erlang:error(baddate, Datetime)
+ error:_ -> erlang:error(baddate, Datetime)
end.
View
3  src/ezic_db.erl
@@ -1,6 +1,7 @@
-module(ezic_db).
-include("include/ezic.hrl").
-include_lib("stdlib/include/qlc.hrl").
+-include_lib("eunit/include/eunit.hrl").
-export([zones/1, rules/1]).
@@ -98,7 +99,7 @@ create_tabs({error, {_, {already_exists,_}}}) ->
mnesia:start(),
ok;
create_tabs(E) ->
- ?debug(E).
+ ?debugVal(E).
View
22 src/ezic_flatten.erl
@@ -26,7 +26,8 @@ flatten() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% recursively processes sets of similar zones until they're all done, passing zone sets to flatten_zone_set/1
+% recursively processes sets of similar zones until they're all done,
+% passing zone sets to flatten_zone_set/1
flatten_zones(Zones) ->
flatten_zones(Zones, []).
@@ -44,8 +45,9 @@ flatten_zones([Z1|_]= AllZones, Flats) ->
-% takes zones one-by-one, gathering relevant rules and creating flat periods of the same gmt offset (#flatzone)
-% This is a recursive solution, eliminating Zones until they've been exhausted
+% takes zones one-by-one, gathering relevant rules and creating flat
+% periods of the same gmt offset (#flatzone). This is a recursive
+% solution, eliminating Zones until they've been exhausted
flatten_zone_set(Zones) ->
flatten_zone_set(?MINFLAT, Zones, []).
@@ -57,13 +59,13 @@ flatten_zone_set(Zones) ->
%
% assumes a new zone every time it is called
flatten_zone_set(_, [], Flats) ->
- Flats;
+ Flats;
flatten_zone_set(FromTimeStub=#flatzone{utc_from=UTCFrom, dstoffset=DSTOffset}
, Zones %[Z1=#zone{rule=RuleName, until=UntilTime, gmtoff=Offset} | _RestZones],
- , Flats) ->
+ , _Flats) ->
- {Zone, RestZones}= ezic_zone:next(Zones, UTCFrom, DSTOffset),
- #zone{rule=RuleName, until=UntilTime, gmtoff=Offset}=Zone,
+ [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},
@@ -131,7 +133,7 @@ flatten_rule_set(FlatStart=#flatzone{utc_from=UTCFrom, dstoffset=DSTOffset, offs
?debugVal(RulesWithDates),
[{EndingRuleDate, EndingRule} | _]= lists:sort(RulesWithDates),
- {ZoneDate, Zone}= ZoneWithDate,
+ {ZoneDate, _Zone}= ZoneWithDate,
?debugVal(EndingRuleDate),
?debugVal(ZoneDate),
@@ -151,9 +153,9 @@ flatten_rule_set(FlatStart=#flatzone{utc_from=UTCFrom, dstoffset=DSTOffset, offs
-finish_and_start_flat(FlatStub=#flatzone{utc_from=UTCFrom}, EndingRule=#rule{}, EndingRuleDate={{ERDY,_,_},_}, Offset, DSTOffset) ->
+finish_and_start_flat(FlatStub=#flatzone{utc_from=_UTCFrom}, EndingRule=#rule{}, _EndingRuleDate={{ERDY,_,_},_}, Offset, DSTOffset) ->
NewFlatStartDates={WD, SD, UD}= ezic_date:for_rule_all(EndingRule, Offset, DSTOffset, ERDY),
- FlatEndDates={WDm, SDm, UDm}= ezic_date:m1s(NewFlatStartDates),
+ _FlatEndDates={WDm, SDm, UDm}= ezic_date:m1s(NewFlatStartDates),
EndFlat= ?ENDFLAT(FlatStub, WDm, SDm, UDm, DSTOffset),
NewFlat1= ?FLAT(WD, SD, UD),
View
10 src/ezic_rule.erl
@@ -26,9 +26,9 @@ parse([Name,FromS,ToS,_Type,InS,OnS,AtS,SaveS,Letters]) ->
% 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, to=RTo}, Offset, DSTOffset, UTCAfter=minimum) ->
+project_next(Rule=#rule{from=RFrom}, Offset, DSTOffset, minimum) ->
ezic_date:for_rule_utc(Rule, Offset, DSTOffset, RFrom);
-project_next(Rule=#rule{from=RFrom, to=RTo}, Offset, DSTOff, UTCAfter={{AY,_,_},_}) ->
+project_next(Rule=#rule{}, Offset, DSTOff, UTCAfter={{AY,_,_},_}) ->
AllYears= years(Rule),
GoodYears= years_after(AY, AllYears),
project_next2(Rule, Offset, UTCAfter, DSTOff, GoodYears).
@@ -40,16 +40,16 @@ project_next(Rule=#rule{from=RFrom, to=RTo}, Offset, DSTOff, UTCAfter={{AY,_,_},
% returns the sorted list of years a rule existed for.
-years(Rule=#rule{from=From, to=only}) ->
+years(#rule{from=From, to=only}) ->
[From];
-years(Rule=#rule{from=From, to=To}) ->
+years(#rule{from=From, to=To}) ->
try lists:seq(From, To)
catch error:function_clause ->
erlang:error(bad_year_range, [From, To])
end.
% returns the years from the list that are greater than OR equal to Y
-years_after(Y, []) ->
+years_after(_, []) ->
[];
years_after(Y, Years) ->
{GOOD, _}= lists:partition(
View
17 src/ezic_zone.erl
@@ -46,10 +46,12 @@ current_as_of_utc(UTCDatetime, TzName) ->
-
+%% returns the active zone for a given utc time
+%% note: requires that flattening be done
+%% this will likely get reworked significantly
get_zone_utc(_, []) ->
erlang:error(no_current);
-get_zone_utc(_UTCDatetime, Zones) ->
+get_zone_utc(_UTCDatetime, _Zones) ->
not_done.
@@ -95,13 +97,16 @@ project_end_utc(Zone=#zone{}, DSTOffset) ->
% Note that dst differences *can* change which zone comes next,
% though it's very unlikely (and does not exist in the current tz database files).
% this method covers that event, anyhow.
+
+%% BAD!!! UCTFrom is not used!
next(ZoneList, UTCFrom, DSTOff) ->
DatedList= lists:map(
fun(Z=#zone{until=Until, gmtoff=Offset})->
- NU= ezic_date:normalize(Until),
- {_,_,UTCDt}= ezic_date:all_times(NU, Offset, DSTOff),
+ NUntil= ezic_date:normalize(Until),
+ {_,_,UTCDt}= ezic_date:all_times(NUntil, Offset, DSTOff),
{UTCDt, Z}
end
, ZoneList),
- [{_,Zone} | DRest]= lists:sort(DatedList),
- {Zone, [R || {_,R}<- DRest]}.
+ FilteredList= lists:filter(fun({IDt,_})-> UTCFrom =< IDt end, DatedList),
+ SortedList= lists:sort(FilteredList),
+ [Z || {_,Z}<- SortedList].
View
55 test/ezic_zone_tests.erl
@@ -32,3 +32,58 @@ project_end_utc_test_() ->
#zone{until={{2010,11,10},#tztime{time={16,20,0}, flag=u}}, gmtoff={-7,0,0}}
, {1,0,0}))
].
+
+
+
+next_datetime_test_() ->
+ BZ=#zone{gmtoff={0,0,0}},
+ AllZones= [
+ Z1=BZ#zone{until={{2010,11,15},#tztime{}}}
+ , Z2=BZ#zone{until={{2010,11,5},#tztime{}}}
+ , Z3=BZ#zone{until={{2010,11,25},#tztime{}}}
+
+ , Zt1=BZ#zone{until={{2010,11,5},#tztime{time={5,0,0}, flag=u}}}
+ , Zt2=BZ#zone{until={{2010,11,5},#tztime{time={12,0,0}, flag=u}}}
+ , Zt3=BZ#zone{until={{2010,11,5},#tztime{time={17,0,0}, flag=u}}}
+
+ , Zy1=BZ#zone{until={{1978,11,5},#tztime{}}}
+ , Zy2=BZ#zone{until={{1979,11,5},#tztime{}}}
+ , Zy3=BZ#zone{until={{1980,11,5},#tztime{}}}
+ ],
+ [
+ % day limits
+ ?_assertMatch([Z2|_], ezic_zone:next(AllZones, {{2010,11,1},{0,0,0}}, {0,0,0}))
+ , ?_assertMatch([Z1|_], ezic_zone:next(AllZones, {{2010,11,6},{0,0,0}}, {0,0,0}))
+ , ?_assertMatch([Z3|_], ezic_zone:next(AllZones, {{2010,11,16},{0,0,0}}, {0,0,0}))
+
+ % time limits
+ , ?_assertMatch([Zt1|_], ezic_zone:next(AllZones, {{2010,11,5},{0,0,1}}, {0,0,0}))
+ , ?_assertMatch([Zt2|_], ezic_zone:next(AllZones, {{2010,11,5},{5,0,1}}, {0,0,0}))
+ , ?_assertMatch([Zt3|_], ezic_zone:next(AllZones, {{2010,11,5},{12,0,1}}, {0,0,0}))
+
+ % year tests
+ , ?_assertMatch([Zy1|_], ezic_zone:next(AllZones, {{1978,11,5},{0,0,0}}, {0,0,0}))
+ , ?_assertMatch([Zy2|_], ezic_zone:next(AllZones, {{1978,11,7},{0,0,0}}, {0,0,0}))
+ , ?_assertMatch([Zy3|_], ezic_zone:next(AllZones, {{1979,11,8},{0,0,0}}, {0,0,0}))
+
+ ].
+
+%% Take 3 zones identical aside from their "time-relativity", each
+%% ending in standard, wall, and universal time, the following tests
+%% show the choice of "next soonest" as deterministic.
+next_relative_time_test_() ->
+ Zones= [
+ ZW=#zone{until={{2010,11,7},#tztime{time={2,0,0}, flag=w}}, gmtoff={-7,0,0}}
+ , ZS=#zone{until={{2010,11,7},#tztime{time={2,0,0}, flag=s}}, gmtoff={-7,0,0}}
+ , ZU=#zone{until={{2010,11,7},#tztime{time={2,0,0}, flag=u}}, gmtoff={-7,0,0}}
+ ],
+ [
+ %% same dst, different from
+ ?_assertMatch([ZW|_], ezic_zone:next(Zones,{{2010,11,7},{6,0,0}},{2,0,0}))
+ , ?_assertMatch([ZS|_], ezic_zone:next(Zones,{{2010,11,7},{7,0,1}},{2,0,0}))
+ , ?_assertMatch([ZU|_], ezic_zone:next(Zones,{{2010,11,7},{1,0,1}},{2,0,0}))
+
+ %% same from, different dst
+ , ?_assertMatch([ZW|_], ezic_zone:next(Zones,{{2010,11,7},{8,50,0}},{0,9,0})) %1:59wt, 1:50st
+ , ?_assertMatch([ZS|_], ezic_zone:next(Zones,{{2010,11,7},{8,50,0}},{0,-1,0})) %1:49wt, 1:50st
+ ].
Please sign in to comment.
Something went wrong with that request. Please try again.