From 22395e2f47231a572677f577acac93c8a9d0b593 Mon Sep 17 00:00:00 2001 From: aj Date: Sun, 14 Nov 2010 00:27:44 -0800 Subject: [PATCH] max_year base case bug fixed. ezic:localtime/1 works. the final flatzone for every Zone should end at "current" for every *_to time. This is inaccurate, but accuracy is only guaranteed up to ?MAX_YEAR (=2500 by default). that working, I fleshed out the few methods required to get ezic:utc_to_localtime/2 working, thus localtime/1 working. I've only tested localtime/1 at this point. additionally, mnesia appears to have its data corrupted every time I stop and start a node. I've got to read up on working with mnesia; it's not behaving as I would expect. --- src/ezic.erl | 29 ++++++++++++++++++++++++++--- src/ezic_date.erl | 6 ++---- src/ezic_db.erl | 19 ++++++++++++++----- src/ezic_flatten.erl | 38 ++++++++++++++++++++++++++++++++++---- 4 files changed, 76 insertions(+), 16 deletions(-) diff --git a/src/ezic.erl b/src/ezic.erl index bd848cb..e045288 100644 --- a/src/ezic.erl +++ b/src/ezic.erl @@ -8,7 +8,13 @@ , next_timechange_after/2 ]). --export([load/1, dev/0, test/0]). +-export([ + load/1 + , dev/0 + , test/0 + , reflatten/0 + , zf/0 + ]). @@ -28,8 +34,14 @@ localtime(TzName) -> utc_to_local(UTCDatetime, TzName) -> - #flatzone{offset=Offset, dstoffset=DSTOffset}= ezic_db:flatzone(UTCDatetime, TzName), - ezic_date:add_offset(ezic_date:add_offset(UTCDatetime, Offset), DSTOffset). + NormalDatetime= ezic_date:normalize(UTCDatetime, u), + #flatzone{offset=Offset, dstoffset=DSTOffset}= ezic_db:flatzone(NormalDatetime, TzName), + + ezic_date:add_offset( + ezic_date:add_offset( + UTCDatetime + , Offset) + , DSTOffset). @@ -57,11 +69,22 @@ load(Folder) -> dev() -> ezic:load(filename:join("priv","tzdata")), ezic_flatten:flatten(), + % Zones= ezic_db:zones("WET"), % ezic_flatten:flatten_all_zones(Zones), ok. +zf() -> + Zones= ezic_db:zones("Asia/Tokyo"), + ezic_flatten:flatten_all_zones(Zones). + + +reflatten() -> + ezic_db:wipe(flatzone), + ezic_flatten:flatten(). + + test() -> lists:foreach( diff --git a/src/ezic_date.erl b/src/ezic_date.erl index ab5302c..a6f0b86 100644 --- a/src/ezic_date.erl +++ b/src/ezic_date.erl @@ -43,6 +43,7 @@ %% USED EXCLUSIVELY FOR COMPARISONS. The resulting "datetime" values may not %% represent true dates or times. %% @todo ensure atom is valid +%% assumes wall time, if no #tztime{} given normalize(A) when is_atom(A) -> A; normalize(Y) when is_integer(Y) -> @@ -253,10 +254,7 @@ compare({Date1, #tztime{time=Time1, flag=F}} Date1 =< Date2 orelse Time1 =< time2; compare(X,Y) -> - XN= normalize(X), - YN= normalize(Y), - compare(XN, YN). - + erlang:error(bad_dates, [X,Y]). equal(X,Y) when X=:=Y -> diff --git a/src/ezic_db.erl b/src/ezic_db.erl index 114316c..11c7891 100644 --- a/src/ezic_db.erl +++ b/src/ezic_db.erl @@ -5,7 +5,7 @@ -export([zones/1, rules/1, flatzones/1, flatzone/2]). --export([wipe/0, init/0, insert_all/1, get_all/1]). +-export([wipe/0, wipe/1, init/0, insert_all/1, get_all/1]). -define(create(Record), @@ -63,10 +63,9 @@ flatzones(TzName) -> flatzone(Date, TzName) -> F = fun()-> Q = qlc:q( - [Fz || Fz=#flatzone{tzname=N, utc_from=UF, utc_to=UT} <- mnesia:table(flatzone) - , N=:=TzName - , ezic_date:compare(UF, Date) - , ezic_date:compare(Date, UT)]), + [Fz || Fz=#flatzone{tzname=N} <- mnesia:table(flatzone) + , N=:=TzName + , ezic_flatten:contains_date(Fz, Date)]), qlc:e(Q) end, {atomic, [FlatZone]}= mnesia:transaction(F), @@ -108,6 +107,16 @@ wipe() -> mnesia:delete_schema([node()]). + +% WARNING: deletes all entries in table Tab +wipe(Tab) -> + mnesia:transaction( + fun()-> + mnesia:delete(Tab, '_', write) + end). + + + create_tabs(ok) -> mnesia:start(), diff --git a/src/ezic_flatten.erl b/src/ezic_flatten.erl index 78df7c5..a71050e 100644 --- a/src/ezic_flatten.erl +++ b/src/ezic_flatten.erl @@ -13,7 +13,10 @@ -define(MAXYEAR, 2500). % last year to process flatzones for. --export([flatten/0]). +-export([ + flatten/0 + , contains_date/2 + ]). %% debug @@ -27,6 +30,12 @@ flatten() -> done. +contains_date(FlatZone, Date) -> + NDate= ezic_date:normalize(Date), + contains_date2(FlatZone, NDate). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % PRIVATE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -47,8 +56,20 @@ flatten_all_zones([Z1|_]= AllZones) -> +contains_date2(FlatZone=#flatzone{utc_from=From, utc_to=To}, {Dt,#tztime{time=T, flag=F}}) + when F=:= u; F=:= g; F=:=z -> + Date={Dt, T}, + ezic_date:compare(From, Date) andalso ezic_date:compare(Date, To); - +contains_date2(FlatZone=#flatzone{std_from=From, std_to=To}, {Dt,#tztime{time=T, flag=s}}) -> + Date={Dt, T}, + ezic_date:compare(From, Date) andalso ezic_date:compare(Date, To); + +contains_date2(FlatZone=#flatzone{wall_from=From, wall_to=To}, {Dt,#tztime{time=T, flag=F}}) + when F=:=w; F=:=undefined -> + Date={Dt, T}, + ezic_date:compare(From, Date) andalso ezic_date:compare(Date, To). + @@ -161,7 +182,9 @@ flatten_rule_set(FlatStart=#flatzone{utc_from=UTCFrom, dstoffset=DSTOffset, offs try maxyear_reached(UTCEndingRuleDate) andalso maxyear_reached(ZoneDate) of true -> ?debugMsg("maxyear reached from flatten_rule_set"), - {Flats, #flatzone{utc_from=maximum}, none}; + {EndFlat, NextFlat}= finish_and_start_flat(max_year, FlatStart, DSTOffset), + NewFlats= [EndFlat | Flats], + {NewFlats, NextFlat, none}; false -> case ezic_date:compare(ZoneDate, UTCEndingRuleDate) of @@ -227,7 +250,14 @@ finish_and_start_flat(FlatStub=#flatzone{}, Zone=#zone{}, EndingDST) -> ?debugVal(EndFlat), % ?debugVal(RetNextFlat), - {EndFlat, RetNextFlat}. + {EndFlat, RetNextFlat}; + +finish_and_start_flat(max_year, FlatStub, DSTOffset) -> + EndFlat= ?ENDFLAT(FlatStub, current, current, current, DSTOffset), + Stop= {{?MAXYEAR+1,1,1},{0,0,0}}, + NextFlat= #flatzone{utc_from=Stop}, + {EndFlat, NextFlat}. + %% both timezone and rule are ending at the same time