Merge remote-tracking branch 'jacktang/gmt-offset-fix'

Conflicts:
	src/localtime.erl
This commit is contained in:
Jesse Gumm 2016-01-31 08:54:38 -06:00
commit 32cb7d9e90
4 changed files with 72 additions and 38 deletions

View file

@ -1,9 +1,10 @@
TZDIR=tzdata
TZ_FILES=$(addprefix $(TZDIR)/, africa antarctica asia australasia backward etcetera europe northamerica southamerica)
tzout: DATE := $(shell date +%F)
tzout: $(TZ_FILES)
TZ_VERSION=`perl -n -e 'm/^VERSION\s*=\s*(\S+)/ and print $$1;' $(TZDIR)/Makefile`; \
./tz-erl --version $$TZ_VERSION -o $@ $^
./tz-erl --version $$TZ_VERSION --date $(DATE) -o $@ $^
$(TZ_FILES): $(TZDIR)

View file

@ -145,15 +145,17 @@ sub process_data {
}
}
# Converts an offset in the format "[+-]?HH:MM" or "[+-]?HH" into minutes.
# For example, "2:00" -> 120, "-0:30" -> -30, "+5" -> 300.
sub offset_minutes {
my ($off, $adj) = @_;
my $convert_offset = sub {
my $m = $_[0];
if ($m =~ m/^([\+\-]?)(?:(\d+):)?(\d+)$/) {
$m = (defined $2 ? $2 : 0) * MPH + $3;
$_[0] =~ m/^([\+\-]?)(\d+)(?::(\d+))?$/
or die "offset \"$_[0]\" did not match";
my $m = $2 * MPH;
if (defined $3) { $m += $3; }
if ($1 eq '-') { $m = -$m; }
}
return $m;
};
@ -256,9 +258,13 @@ sub zone_line {
# We ignore any zone line that has a definite until (end) time that
# is in the past.
if (defined $until) {
my $until_year = ($until =~ m/^(\d+)/)[0];
if ($until_year >= $current_year) {
die "until $until not handled";
my ($until_year, $until_month, $until_day) = split_ymd($until);
if (($until_year > $current_year) ||
(($until_year == $current_year) &&
(($until_month > $current_month) ||
(($until_month == $current_month) &&
($until_day >= $current_day))))) {
"future until \"$until\" not handled";
}
return;
}
@ -286,7 +292,10 @@ sub zone_line {
$rule1 = $rule2 = RULE_NULL;
} elsif (scalar(@rules) == 1) {
# One active rule. This is a year that DST started or stopped
# being observed
# being observed. erlang_localtime doesn't handle this. If DST
# stopped being observed in this year, don't output a DST rule.
# If DST started being observed, do. (Except that we don't handle
# this yet.)
print STDERR Data::Dump::dump(\@rules), "\n";
die "one rule for $name";
$name1 = zonename($format, $rules[0]->[RULE_LETTERS], undef);
@ -427,6 +436,23 @@ INIT {
%dow_from_name= map { $dow_to_name[$_] => $_ } (0..$#dow_to_name);
}
sub split_ymd {
my ($ymd) = @_;
$ymd =~ m/^(\d+)(?:\s+(\w+)(?:\s+(\d+)))?/
or die "parse \"$ymd\" for ymd failed";
my $year = $1;
my $month = do {
if (defined $2) {
defined $mon_from_name{$2} or die "parse \"$ymd\" for month failed";
$mon_from_name{$2};
} else {
0
}
};
my $day = defined $3 ? $3 : 0;
return ($year, $month, $day);
}
sub on_to_day_of_month {
my ($on, $year, $month) = @_;

View file

@ -427,33 +427,33 @@
{"Eire",{"GMT","GMT"},{"IST","IST"},0,60,{last,sun,mar},{1,0},{last,sun,oct},{2,0}},
{"Etc/GMT",{"GMT","GMT"},undef,0,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+0",{"GMT","GMT"},undef,0,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+1",{"GMT+1","GMT+1"},undef,-1,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+10",{"GMT+10","GMT+10"},undef,-10,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+11",{"GMT+11","GMT+11"},undef,-11,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+12",{"GMT+12","GMT+12"},undef,-12,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+2",{"GMT+2","GMT+2"},undef,-2,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+3",{"GMT+3","GMT+3"},undef,-3,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+4",{"GMT+4","GMT+4"},undef,-4,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+5",{"GMT+5","GMT+5"},undef,-5,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+6",{"GMT+6","GMT+6"},undef,-6,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+7",{"GMT+7","GMT+7"},undef,-7,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+8",{"GMT+8","GMT+8"},undef,-8,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+9",{"GMT+9","GMT+9"},undef,-9,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+1",{"GMT+1","GMT+1"},undef,60,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+10",{"GMT+10","GMT+10"},undef,600,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+11",{"GMT+11","GMT+11"},undef,660,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+12",{"GMT+12","GMT+12"},undef,720,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+2",{"GMT+2","GMT+2"},undef,120,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+3",{"GMT+3","GMT+3"},undef,180,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+4",{"GMT+4","GMT+4"},undef,240,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+5",{"GMT+5","GMT+5"},undef,300,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+6",{"GMT+6","GMT+6"},undef,360,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+7",{"GMT+7","GMT+7"},undef,420,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+8",{"GMT+8","GMT+8"},undef,480,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT+9",{"GMT+9","GMT+9"},undef,540,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-0",{"GMT","GMT"},undef,0,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-1",{"GMT-1","GMT-1"},undef,1,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-10",{"GMT-10","GMT-10"},undef,10,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-11",{"GMT-11","GMT-11"},undef,11,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-12",{"GMT-12","GMT-12"},undef,12,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-13",{"GMT-13","GMT-13"},undef,13,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-14",{"GMT-14","GMT-14"},undef,14,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-2",{"GMT-2","GMT-2"},undef,2,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-3",{"GMT-3","GMT-3"},undef,3,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-4",{"GMT-4","GMT-4"},undef,4,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-5",{"GMT-5","GMT-5"},undef,5,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-6",{"GMT-6","GMT-6"},undef,6,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-7",{"GMT-7","GMT-7"},undef,7,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-8",{"GMT-8","GMT-8"},undef,8,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-9",{"GMT-9","GMT-9"},undef,9,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-1",{"GMT-1","GMT-1"},undef,-60,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-10",{"GMT-10","GMT-10"},undef,-600,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-11",{"GMT-11","GMT-11"},undef,-660,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-12",{"GMT-12","GMT-12"},undef,-720,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-13",{"GMT-13","GMT-13"},undef,-780,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-14",{"GMT-14","GMT-14"},undef,-840,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-2",{"GMT-2","GMT-2"},undef,-120,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-3",{"GMT-3","GMT-3"},undef,-180,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-4",{"GMT-4","GMT-4"},undef,-240,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-5",{"GMT-5","GMT-5"},undef,-300,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-6",{"GMT-6","GMT-6"},undef,-360,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-7",{"GMT-7","GMT-7"},undef,-420,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-8",{"GMT-8","GMT-8"},undef,-480,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT-9",{"GMT-9","GMT-9"},undef,-540,0,undef,{0,0},undef,{0,0}},
{"Etc/GMT0",{"GMT","GMT"},undef,0,0,undef,{0,0},undef,{0,0}},
{"Etc/Greenwich",{"GMT","GMT"},undef,0,0,undef,{0,0},undef,{0,0}},
{"Etc/UCT",{"UCT","UCT"},undef,0,0,undef,{0,0},undef,{0,0}},

View file

@ -20,6 +20,7 @@
,get_timezone/1
,list_timezones/0
,adjust_datetime/2
,fmt_shift/1
]).
% utc_to_local(UtcDateTime, Timezone) -> LocalDateTime | [LocalDateTime, DstLocalDateTime] | {error, ErrDescr}
@ -214,6 +215,8 @@ fmt_shift({'+', H, M}) ->
H * 60 + M;
fmt_shift({'-', H, M}) ->
-(H * 60 + M);
fmt_shift(0) ->
0;
fmt_shift(Any) ->
throw(Any).
@ -231,14 +234,18 @@ tr_char([H|T], From, To, Acc) ->
end.
-define(SPACE_CHAR, 32).
get_timezone_inner(TimeZone) ->
get_timezone_inner(TimeZone) when is_binary(TimeZone) ->
get_timezone_inner(erlang:binary_to_list(TimeZone));
get_timezone_inner(TimeZone) when is_list(TimeZone) ->
TimeZoneNoSpaces = tr_char(TimeZone, ?SPACE_CHAR, $_),
case dict:find(TimeZoneNoSpaces, ?tz_index) of
error ->
TimeZoneNoSpaces;
{ok, [TZName | _]} ->
TZName
end.
end;
get_timezone_inner(_) ->
throw({error, "Timezone should be string/binary"}).
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").