Files
ezic/src/ezic_zone.erl
aj c976e63349 removed all warnings. fixed bug in ezic_zone:next/3. unit tests for ezic_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.
2010-11-11 23:52:10 -08:00

113 lines
2.6 KiB
Erlang

-module(ezic_zone).
-include("include/ezic.hrl").
-include_lib("eunit/include/eunit.hrl").
-export([
parse/1
, current/1
, current_as_of_utc/2
, split_by_name/2
, offset_sec/1
, project_end/2
, project_end_utc/2
, next/3
]).
parse([Name,GmtOffS,Rule,FormatS | UntilTokens]) ->
% ?debugVal(GmtOffS),
GmtOff= ezic_parse:time_val(GmtOffS),
Until = ezic_parse:until(UntilTokens),
Format= ezic_parse:tz_abbr(FormatS),
{ok, #zone{
name=Name, gmtoff=GmtOff, rule=Rule,
format=Format, until=Until
}}.
current(TzName) ->
current_as_of_utc(erlang:universaltime(), TzName).
current_as_of_utc(UTCDatetime, TzName) ->
Zones= ezic_db:zones(TzName),
get_zone_utc(UTCDatetime, Zones).
%% 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) ->
not_done.
% returns {[SimilarZone], [DifferentZone]}
% where Similar Zones are those with the same name as Zone
% and DifferentZones are all the rest
split_by_name(#zone{name=N}, Zones) ->
lists:partition(
fun(#zone{name=NI}) ->
N =:= NI
end
, Zones).
% @bug doesn't normalize times. Times are self-relative (to standard time), and Now may come from any timezone unless we're careful about that.
%% older_zone(#zone{until=Until}, UTCDatetime) ->
%% ezic_date:compare(Until, UTCDatetime).
offset_sec(Zone) ->
calendar:time_to_seconds((Zone#zone.gmtoff)#tztime.time).
% returns the UTC datetime projected for zone end (given current DST Offset)
project_end(#zone{until=Until, gmtoff=Offset}, DSTOffset) ->
ezic_date:all_times(Until, Offset, DSTOffset).
% returns just the UTC datetime projected for zone end
project_end_utc(Zone=#zone{}, DSTOffset) ->
{_,_,UTCDatetime}= project_end(Zone, DSTOffset),
UTCDatetime.
% returns {Zone, Rest} where Zone is the next zone after UTCFrom,
% subject to the DST offset.
% 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})->
NUntil= ezic_date:normalize(Until),
{_,_,UTCDt}= ezic_date:all_times(NUntil, Offset, DSTOff),
{UTCDt, Z}
end
, ZoneList),
FilteredList= lists:filter(fun({IDt,_})-> UTCFrom =< IDt end, DatedList),
SortedList= lists:sort(FilteredList),
[Z || {_,Z}<- SortedList].