| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package DateTime::TimeZone::OlsonDB::Zone; |
|
2
|
|
|
|
|
|
|
|
|
3
|
13
|
|
|
13
|
|
133
|
use strict; |
|
|
13
|
|
|
|
|
53
|
|
|
|
13
|
|
|
|
|
549
|
|
|
4
|
13
|
|
|
13
|
|
75
|
use warnings; |
|
|
13
|
|
|
|
|
31
|
|
|
|
13
|
|
|
|
|
658
|
|
|
5
|
13
|
|
|
13
|
|
73
|
use namespace::autoclean; |
|
|
13
|
|
|
|
|
27
|
|
|
|
13
|
|
|
|
|
90
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '2.67'; |
|
8
|
|
|
|
|
|
|
|
|
9
|
13
|
|
|
13
|
|
1266
|
use DateTime::TimeZone; |
|
|
13
|
|
|
|
|
30
|
|
|
|
13
|
|
|
|
|
352
|
|
|
10
|
13
|
|
|
13
|
|
65
|
use DateTime::TimeZone::OlsonDB; |
|
|
13
|
|
|
|
|
27
|
|
|
|
13
|
|
|
|
|
338
|
|
|
11
|
13
|
|
|
13
|
|
68
|
use DateTime::TimeZone::OlsonDB::Change; |
|
|
13
|
|
|
|
|
23
|
|
|
|
13
|
|
|
|
|
331
|
|
|
12
|
13
|
|
|
13
|
|
8414
|
use DateTime::TimeZone::OlsonDB::Observance; |
|
|
13
|
|
|
|
|
49
|
|
|
|
13
|
|
|
|
|
722
|
|
|
13
|
13
|
|
|
13
|
|
235
|
use List::Util qw( first max ); |
|
|
13
|
|
|
|
|
43
|
|
|
|
13
|
|
|
|
|
17997
|
|
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
sub new { |
|
16
|
0
|
|
|
0
|
0
|
|
my $class = shift; |
|
17
|
0
|
|
|
|
|
|
my %p = @_; |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
my $self = { |
|
20
|
|
|
|
|
|
|
name => $p{name}, |
|
21
|
|
|
|
|
|
|
observances => $p{observances}, |
|
22
|
0
|
|
|
|
|
|
changes => [], |
|
23
|
|
|
|
|
|
|
infinite_rules => {}, |
|
24
|
|
|
|
|
|
|
}; |
|
25
|
|
|
|
|
|
|
|
|
26
|
0
|
|
|
|
|
|
return bless $self, $class; |
|
27
|
|
|
|
|
|
|
} |
|
28
|
|
|
|
|
|
|
|
|
29
|
0
|
|
|
0
|
0
|
|
sub name { $_[0]->{name} } |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub last_rules_year { |
|
32
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
33
|
0
|
|
|
|
|
|
my $odb = shift; |
|
34
|
|
|
|
|
|
|
|
|
35
|
0
|
|
|
|
|
|
my $last_rule = $self->{observances}[-1]{rules}; |
|
36
|
|
|
|
|
|
|
|
|
37
|
0
|
0
|
|
|
|
|
return unless $last_rule; |
|
38
|
|
|
|
|
|
|
|
|
39
|
0
|
|
|
|
|
|
my @rules = $odb->rules_by_name($last_rule); |
|
40
|
|
|
|
|
|
|
|
|
41
|
0
|
|
|
|
|
|
return $rules[-1]->min_year(); |
|
42
|
|
|
|
|
|
|
} |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
sub expand_observances { |
|
45
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
46
|
0
|
|
|
|
|
|
my $odb = shift; |
|
47
|
0
|
|
|
|
|
|
my $max_year = shift; |
|
48
|
|
|
|
|
|
|
|
|
49
|
0
|
|
|
|
|
|
my $prev_until; |
|
50
|
|
|
|
|
|
|
## no critic (ControlStructures::ProhibitCStyleForLoops) |
|
51
|
0
|
|
|
|
|
|
for ( my $x = 0; $x < @{ $self->{observances} }; $x++ ) { |
|
|
0
|
|
|
|
|
|
|
|
52
|
0
|
|
|
|
|
|
my %p = %{ $self->{observances}[$x] }; |
|
|
0
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
|
|
54
|
0
|
|
|
|
|
|
my $rules_name = delete $p{rules}; |
|
55
|
|
|
|
|
|
|
|
|
56
|
0
|
0
|
|
|
|
|
my $last_offset_from_std |
|
57
|
|
|
|
|
|
|
= $self->last_change ? $self->last_change->offset_from_std : 0; |
|
58
|
0
|
0
|
|
|
|
|
my $last_offset_from_utc |
|
59
|
|
|
|
|
|
|
= $self->last_change ? $self->last_change->offset_from_utc : 0; |
|
60
|
|
|
|
|
|
|
|
|
61
|
0
|
|
|
|
|
|
my $obs = DateTime::TimeZone::OlsonDB::Observance->new( |
|
62
|
|
|
|
|
|
|
%p, |
|
63
|
|
|
|
|
|
|
utc_start_datetime => $prev_until, |
|
64
|
|
|
|
|
|
|
rules => [ $odb->rules_by_name($rules_name) ], |
|
65
|
|
|
|
|
|
|
last_offset_from_utc => $last_offset_from_utc, |
|
66
|
|
|
|
|
|
|
last_offset_from_std => $last_offset_from_std, |
|
67
|
|
|
|
|
|
|
); |
|
68
|
|
|
|
|
|
|
|
|
69
|
0
|
|
|
|
|
|
my $rule = $obs->first_rule; |
|
70
|
0
|
0
|
|
|
|
|
my $letter = $rule ? $rule->letter : q{}; |
|
71
|
|
|
|
|
|
|
|
|
72
|
0
|
0
|
|
|
|
|
my $change = DateTime::TimeZone::OlsonDB::Change->new( |
|
73
|
|
|
|
|
|
|
type => 'observance', |
|
74
|
|
|
|
|
|
|
utc_start_datetime => $obs->utc_start_datetime, |
|
75
|
|
|
|
|
|
|
local_start_datetime => $obs->local_start_datetime, |
|
76
|
|
|
|
|
|
|
short_name => $obs->formatted_short_name( $letter, $rule ), |
|
77
|
|
|
|
|
|
|
observance => $obs, |
|
78
|
|
|
|
|
|
|
$rule ? ( rule => $rule ) : (), |
|
79
|
|
|
|
|
|
|
); |
|
80
|
|
|
|
|
|
|
|
|
81
|
0
|
0
|
|
|
|
|
if ($DateTime::TimeZone::OlsonDB::DEBUG) { |
|
82
|
|
|
|
|
|
|
## no critic (InputOutput::RequireCheckedSyscalls) |
|
83
|
0
|
|
|
|
|
|
print "Adding observance change ...\n"; |
|
84
|
|
|
|
|
|
|
|
|
85
|
0
|
|
|
|
|
|
$change->_debug_output; |
|
86
|
|
|
|
|
|
|
} |
|
87
|
|
|
|
|
|
|
|
|
88
|
0
|
|
|
|
|
|
$self->add_change($change); |
|
89
|
|
|
|
|
|
|
|
|
90
|
0
|
0
|
|
|
|
|
if ( $obs->rules ) { |
|
91
|
0
|
|
|
|
|
|
$obs->expand_from_rules( $self, $max_year ); |
|
92
|
|
|
|
|
|
|
} |
|
93
|
|
|
|
|
|
|
|
|
94
|
0
|
0
|
|
|
|
|
$prev_until = $obs->until( |
|
95
|
|
|
|
|
|
|
$self->last_change ? $self->last_change->offset_from_std : 0 ); |
|
96
|
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
# last observance |
|
98
|
0
|
0
|
|
|
|
|
if ( $x == $#{ $self->{observances} } ) { |
|
|
0
|
|
|
|
|
|
|
|
99
|
0
|
|
|
|
|
|
foreach my $rule ( $obs->rules ) { |
|
100
|
0
|
0
|
|
|
|
|
if ( $rule->is_infinite ) { |
|
101
|
0
|
|
|
|
|
|
$self->add_infinite_rule($rule); |
|
102
|
|
|
|
|
|
|
} |
|
103
|
|
|
|
|
|
|
} |
|
104
|
|
|
|
|
|
|
} |
|
105
|
|
|
|
|
|
|
} |
|
106
|
|
|
|
|
|
|
} |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
sub add_change { |
|
109
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
110
|
0
|
|
|
|
|
|
my $change = shift; |
|
111
|
|
|
|
|
|
|
|
|
112
|
0
|
0
|
|
|
|
|
if ( defined $change->utc_start_datetime ) { |
|
113
|
0
|
0
|
0
|
|
|
|
if ( @{ $self->{changes} } |
|
|
0
|
|
0
|
|
|
|
|
|
114
|
|
|
|
|
|
|
&& $self->{changes}[-1]->utc_start_datetime |
|
115
|
|
|
|
|
|
|
&& $self->{changes}[-1]->utc_start_datetime |
|
116
|
|
|
|
|
|
|
== $change->utc_start_datetime ) { |
|
117
|
0
|
0
|
0
|
|
|
|
if ( $self->{changes}[-1]->rule && $change->observance ) { |
|
118
|
|
|
|
|
|
|
## no critic (InputOutput::RequireCheckedSyscalls) |
|
119
|
0
|
0
|
|
|
|
|
print |
|
120
|
|
|
|
|
|
|
" Ignoring previous rule change, that starts the same time as current observance change\n\n" |
|
121
|
|
|
|
|
|
|
if $DateTime::TimeZone::OlsonDB::DEBUG; |
|
122
|
|
|
|
|
|
|
|
|
123
|
0
|
|
|
|
|
|
$self->{changes}[-1] = $change; |
|
124
|
|
|
|
|
|
|
|
|
125
|
0
|
|
|
|
|
|
return; |
|
126
|
|
|
|
|
|
|
} |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
die |
|
129
|
0
|
|
|
|
|
|
"Cannot add two different changes that have the same UTC start datetime!\n"; |
|
130
|
|
|
|
|
|
|
} |
|
131
|
|
|
|
|
|
|
|
|
132
|
0
|
|
|
|
|
|
my $last_change = $self->last_change; |
|
133
|
|
|
|
|
|
|
|
|
134
|
0
|
0
|
0
|
|
|
|
if ( $last_change->short_name eq $change->short_name |
|
|
|
|
0
|
|
|
|
|
|
135
|
|
|
|
|
|
|
&& $last_change->total_offset == $change->total_offset |
|
136
|
|
|
|
|
|
|
&& $last_change->is_dst == $change->is_dst ) { |
|
137
|
0
|
|
0
|
|
|
|
my $last_rule = $last_change->rule || q{}; |
|
138
|
0
|
|
0
|
|
|
|
my $new_rule = $change->rule || q{}; |
|
139
|
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
## no critic (InputOutput::RequireCheckedSyscalls) |
|
141
|
0
|
0
|
|
|
|
|
print "Skipping identical change\n" |
|
142
|
|
|
|
|
|
|
if $DateTime::TimeZone::OlsonDB::DEBUG; |
|
143
|
0
|
|
|
|
|
|
return; |
|
144
|
|
|
|
|
|
|
} |
|
145
|
|
|
|
|
|
|
|
|
146
|
0
|
|
|
|
|
|
push @{ $self->{changes} }, $change; |
|
|
0
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
} |
|
148
|
|
|
|
|
|
|
else { |
|
149
|
0
|
0
|
|
|
|
|
if ( $self->{earliest} ) { |
|
150
|
0
|
|
|
|
|
|
die 'There can only be one earliest time zone change!'; |
|
151
|
|
|
|
|
|
|
} |
|
152
|
|
|
|
|
|
|
else { |
|
153
|
0
|
|
|
|
|
|
$self->{earliest} = $change; |
|
154
|
|
|
|
|
|
|
} |
|
155
|
|
|
|
|
|
|
} |
|
156
|
|
|
|
|
|
|
} |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
sub add_infinite_rule { |
|
159
|
0
|
|
|
0
|
0
|
|
$_[0]->{infinite_rules}{ $_[1] } = $_[1]; |
|
160
|
|
|
|
|
|
|
} |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
sub last_change { |
|
163
|
0
|
0
|
0
|
0
|
0
|
|
return unless @{ $_[0]->{changes} } || $_[0]->{earliest}; |
|
|
0
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
return ( |
|
165
|
0
|
|
|
|
|
|
@{ $_[0]->{changes} } |
|
166
|
|
|
|
|
|
|
? $_[0]->{changes}[-1] |
|
167
|
|
|
|
|
|
|
: $_[0]->{earliest} |
|
168
|
0
|
0
|
|
|
|
|
); |
|
169
|
|
|
|
|
|
|
} |
|
170
|
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
sub sorted_changes { |
|
172
|
|
|
|
|
|
|
( |
|
173
|
|
|
|
|
|
|
( defined $_[0]->{earliest} ? $_[0]->{earliest} : () ), |
|
174
|
0
|
|
|
|
|
|
sort { $a->utc_start_datetime <=> $b->utc_start_datetime } |
|
175
|
0
|
0
|
|
0
|
0
|
|
@{ $_[0]->{changes} } |
|
|
0
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
); |
|
177
|
|
|
|
|
|
|
} |
|
178
|
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
sub infinite_rules { |
|
180
|
0
|
0
|
|
|
|
|
my @v = sort { $a->min_year <=> $b->min_year || $a->month cmp $b->month } |
|
181
|
0
|
|
|
0
|
0
|
|
values %{ $_[0]->{infinite_rules} }; |
|
|
0
|
|
|
|
|
|
|
|
182
|
0
|
|
|
|
|
|
return @v; |
|
183
|
|
|
|
|
|
|
} |
|
184
|
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
1; |