From 216a8d9ff8cdd8b774d7c783bfd69a83bb1cc09f Mon Sep 17 00:00:00 2001 From: aj Date: Tue, 9 Nov 2010 23:32:25 -0800 Subject: [PATCH] brainstorming the flattening algorithm, slight API change --- notes/flatten_pseudocode.svg | 249 ++++++++++++++++++++------------- notes/rule_parsing_by_hand.txt | 101 +++++++++++++ src/ezic_flatten.erl | 9 +- 3 files changed, 259 insertions(+), 100 deletions(-) create mode 100644 notes/rule_parsing_by_hand.txt diff --git a/notes/flatten_pseudocode.svg b/notes/flatten_pseudocode.svg index 1fdb68b..4220ee5 100644 --- a/notes/flatten_pseudocode.svg +++ b/notes/flatten_pseudocode.svg @@ -22,9 +22,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="0.7" - inkscape:cx="215.08492" - inkscape:cy="417.34138" + inkscape:zoom="0.49497475" + inkscape:cx="96.867054" + inkscape:cy="484.06647" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" @@ -157,7 +157,8 @@ + inkscape:label="page1" + style="display:inline"> + style="fill:#fcaf3e;stroke:#f57900;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0" /> + style="fill:#8ae234;stroke:#4e9a06;stroke-width:3.99999952;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0" /> foreach zone get its rules - - - - - - - - - - - - - - One Rule + sodipodi:role="line"> get its rules sort them flatten them foreach rule and zoneflattening rules: convert datetime to UTC -using zoneinfo - - + id="tspan2913">offset= zone's STD offsetprevious_dst= noneprevious_end= minimumuntil zone_end dst= previous_dst begin= previous_end dchange= next change after begin if zone ends before dchange: convert zone end to all times create #rulerange zone_end else convert dchange to all times create #rulerange previous_end= dchange previous_dst= dchange's DST setting next rule diff --git a/notes/rule_parsing_by_hand.txt b/notes/rule_parsing_by_hand.txt new file mode 100644 index 0000000..9f56c4e --- /dev/null +++ b/notes/rule_parsing_by_hand.txt @@ -0,0 +1,101 @@ +New York: + +zone1. + offset= {-4, 56, 02} + ends= {{1883, 11, 18}, {12,03,57}, w} + or {{1883, 11, 18}, {12,03,57}, s} + or {{1883, 11, 18}, {16,59,59}, u} + + +from minimum + dst= none + + % zone change + end= zone1.ends + + + + +zone2. + offset= {-5,0,0} + ends= {{1920,1,1}, {0,0,0}, w} + + +from zone1.ends+1sec + dst= none + + % dst event + end= {{1918,3,31}, {1,59,59}, w} + or {{1918,3,31}, {1,59,59}, s} + or {{1918,3,31}, {6,59,59}, u} + + +from {{1918,3,31}, {7,0,0}, u} + dst= {1,0,0} + + % dst event + end= {{1918,10,27}, {1,59,59}, w} + or {{1918,10,27}, {0,59,59}, s} + or {{1918,10,27}, {5,59,59}, u} + + +from {{1918,10,27}, {6,0,0}, u} + dst= none + + % dst event + end= {{1919,3,30}, {1,59,59}, w} + or {{1919,3,30}, {1,59,59}, s} + or {{1919,3,30}, {6,59,59}, u} + + +from {{1919,3,30}, {7,0,0}, u} + dst= {1,0,0} + + % dst event + end= {{1919,10,26}, {1,59,59}, w} + or {{1919,10,26}, {0,59,59}, s} + or {{1919,10,26}, {5,59,59}, u} + + +from {{1919,10,26}, {5,59,59}, u} + dst= none + + % zone end + end= {{1919,12,31}, {23,59,59}, w} + or {{1919,12,31}, {23,59,59}, s} + or {{1920,1,1}, {4,59,59}, u} + + +zone3. + offset= {-5,0,0} + ends= {{1942,1,1}, {0,0,0}, w} + +from {{1920,1,1}, {5,0,0}, u} + dst= none %from previous + + + +GENERAL PATTERN + +in zoneX. + offset= {HH,MM,SS} + end= {{Y,M,D},{HH,MM,SS}, w} %% usually wall-time, can be otherwise + +from previous.ends +1sec + dst= previous.dst + + calculate all times for begin (w/s/u) + + foreach rule: + given begin, current dst and offset, + - calculate oldest change > begin %% may be none + nextRule= the rule with the earliest of these dates + + if nextRule.start > zoneX.end: + end= zoneX.end-1sec + next_zone (offset & end) + else: + end= oldest.time-1sec + + nextDst= nextRule.dst + nextBegin= end+1sec diff --git a/src/ezic_flatten.erl b/src/ezic_flatten.erl index e4be16c..b6df047 100644 --- a/src/ezic_flatten.erl +++ b/src/ezic_flatten.erl @@ -25,6 +25,11 @@ flatten() -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% 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, []). + + make_next_flat(#flatzone{wall_to=W, std_to=S, utc_to=U, offset=O}) -> make_next_flat({W,S,U}, O); @@ -53,10 +58,6 @@ end_flat(Flat=#flatzone{}, {W,S,U}) -> -% 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, []). - flatten_zones([], Flats) -> Flats; flatten_zones([Z1|_]= AllZones, Flats) ->