alerted to buginess in README. added notes & zic reference. removed local_to_utc conversion for now.

Time comparisons are patently wrong. They do not consider s/w/u/g/z time modifiers, so the comparisons can be off by hours. At least 24 hours within any time or zone change, ezic will give unreliable results.
I think a solution can involve "flattening" the data, starting from the earliest time possible for each zone/rule, going forward.
There exist ambiguous local times for zones and rules. For example, on Nov 7th, in Los Angeles, the times from 1:00:00am to 1:59:59am were repeated, once for PDT and once for PST. Given a local time in that zone between those times, we cannot determine what UTC time is unambiguously. Similar for Zone transitions where fall-back occurs.
This commit is contained in:
aj
2010-11-07 12:52:51 -08:00
parent 4d95017b7f
commit 329f699e51
7 changed files with 609 additions and 51 deletions

View File

@@ -4,8 +4,8 @@
-export([
localtime/1
, utc_to_local/2
, utc_from_local/2
, zone_convert/3
% , local_to_utc/2
% , zone_convert/3
, next_timechange/1
, next_timechange/2
]).
@@ -28,28 +28,28 @@ localtime(TzName) ->
utc_to_local(erlang:universaltime(), TzName).
utc_to_local(Datetime, TzName) ->
{ok, Zone, Rule}= current(Datetime, TzName),
SecDiff= offset(Zone, Rule),
date_add(Datetime, SecDiff).
utc_to_local(UTCDatetime, TzName) ->
{ok, Zone, Rule}= current_as_of_utc(UTCDatetime, TzName),
SecDiff= time_offset(Zone, Rule),
date_add(UTCDatetime, SecDiff).
utc_from_local(Datetime, TzName) ->
{ok, Zone, Rule}= current(Datetime, TzName),
SecDiff= offset(Zone, Rule),
date_subtract(Datetime, SecDiff).
%% local_to_utc(Datetime, TzName) ->
%% {ok, Zone, Rule}= current_as_of_local(Datetime, TzName),
%% SecDiff= time_offset(Zone, Rule),
%% date_subtract(Datetime, SecDiff).
zone_convert(Datetime, FromTimeZone, ToTimeZone) ->
UTC= utc_from_local(Datetime, FromTimeZone),
utc_to_local(UTC, ToTimeZone).
%% zone_convert(Datetime, FromTimeZone, ToTimeZone) ->
%% UTC= local_to_utc(Datetime, FromTimeZone),
%% utc_to_local(UTC, ToTimeZone).
next_timechange(TzName) ->
next_timechange(localtime(TzName), TzName).
next_timechange(erlang:universaltime(), TzName).
next_timechange(Datetime, TzName) ->
next_timechange(UtcDatetime, TzName) ->
not_done.
@@ -84,23 +84,19 @@ test() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
current(Datetime, TzName) ->
Zones= ezic_db:zones(TzName),
% ?debug("All Zones: ~p", [Zones]),
CZone= ezic_zone:current(Datetime, Zones),
% ?debug("Current Zone: ~p", [CZone]),
current_as_of_utc(UTCDatetime, TzName) ->
CZone= ezic_zone:current_as_of_utc(UTCDatetime, TzName),
RuleName= CZone#zone.rule,
Rules= ezic_db:rules(RuleName),
% ?debug("All Rules: ~p", [Rules]),
CRule= ezic_rule:current(Datetime, Rules),
% ?debug("Current Rule: ~p", [CRule]),
CRule= ezic_rule:current_as_of_utc(UTCDatetime, Rules),
{ok, CZone, CRule}.
%%current_as_of_local(Datetime, TzName) ->
%% not_done.
offset(Zone, Rule) ->
time_offset(Zone, Rule) ->
OffsetSec= ezic_zone:offset_sec(Zone),
DSTSec= ezic_rule:dst_sec(Rule),
OffsetSec + DSTSec.