line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package DateTime::TimeZone::OlsonDB::Change; |
2
|
|
|
|
|
|
|
|
3
|
3
|
|
|
3
|
|
19
|
use strict; |
|
3
|
|
|
|
|
7
|
|
|
3
|
|
|
|
|
95
|
|
4
|
3
|
|
|
3
|
|
17
|
use warnings; |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
67
|
|
5
|
3
|
|
|
3
|
|
16
|
use namespace::autoclean; |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
20
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '2.60'; |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
sub new { |
10
|
0
|
|
|
0
|
0
|
|
my $class = shift; |
11
|
0
|
|
|
|
|
|
my %p = @_; |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
# These are almost always mutually exclusive, except when adding |
14
|
|
|
|
|
|
|
# an observance change and the last rule has no offset, but the |
15
|
|
|
|
|
|
|
# new observance has an anonymous rule. In that case, prefer the |
16
|
|
|
|
|
|
|
# offset from std defined in the observance to that in the |
17
|
|
|
|
|
|
|
# previous rule (what a mess!). |
18
|
0
|
0
|
|
|
|
|
if ( $p{type} eq 'observance' ) { |
19
|
0
|
0
|
|
|
|
|
$p{offset_from_std} = $p{rule}->offset_from_std if defined $p{rule}; |
20
|
|
|
|
|
|
|
$p{offset_from_std} = $p{observance}->offset_from_std |
21
|
0
|
0
|
|
|
|
|
if $p{observance}->offset_from_std; |
22
|
0
|
|
0
|
|
|
|
$p{offset_from_std} ||= 0; |
23
|
|
|
|
|
|
|
} |
24
|
|
|
|
|
|
|
else { |
25
|
0
|
|
|
|
|
|
$p{offset_from_std} = $p{observance}->offset_from_std; |
26
|
0
|
0
|
|
|
|
|
$p{offset_from_std} = $p{rule}->offset_from_std if defined $p{rule}; |
27
|
|
|
|
|
|
|
} |
28
|
|
|
|
|
|
|
|
29
|
0
|
|
|
|
|
|
$p{offset_from_utc} = $p{observance}->offset_from_utc; |
30
|
|
|
|
|
|
|
|
31
|
0
|
|
|
|
|
|
$p{is_dst} = 0; |
32
|
0
|
0
|
0
|
|
|
|
$p{is_dst} = 1 if $p{rule} && $p{rule}->offset_from_std; |
33
|
0
|
0
|
|
|
|
|
$p{is_dst} = 1 if $p{observance}->offset_from_std; |
34
|
|
|
|
|
|
|
|
35
|
0
|
0
|
|
|
|
|
if ( $p{short_name} =~ m{([\-\+\w]+)/([\-\+\w]+)} ) { |
36
|
0
|
0
|
|
|
|
|
$p{short_name} = $p{is_dst} ? $2 : $1; |
37
|
|
|
|
|
|
|
} |
38
|
|
|
|
|
|
|
|
39
|
0
|
|
|
|
|
|
return bless \%p, $class; |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
|
42
|
0
|
|
|
0
|
0
|
|
sub utc_start_datetime { $_[0]->{utc_start_datetime} } |
43
|
0
|
|
|
0
|
0
|
|
sub local_start_datetime { $_[0]->{local_start_datetime} } |
44
|
0
|
|
|
0
|
0
|
|
sub short_name { $_[0]->{short_name} } |
45
|
0
|
|
|
0
|
0
|
|
sub is_dst { $_[0]->{is_dst} } |
46
|
0
|
|
|
0
|
0
|
|
sub observance { $_[0]->{observance} } |
47
|
0
|
|
|
0
|
0
|
|
sub rule { $_[0]->{rule} } |
48
|
0
|
|
|
0
|
0
|
|
sub offset_from_utc { $_[0]->{offset_from_utc} } |
49
|
0
|
|
|
0
|
0
|
|
sub offset_from_std { $_[0]->{offset_from_std} } |
50
|
0
|
|
|
0
|
0
|
|
sub total_offset { $_[0]->offset_from_utc + $_[0]->offset_from_std } |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
sub two_changes_as_span { |
53
|
0
|
|
|
0
|
0
|
|
my ( $c1, $c2 ) = @_; |
54
|
|
|
|
|
|
|
|
55
|
0
|
|
|
|
|
|
my ( $utc_start, $local_start ); |
56
|
|
|
|
|
|
|
|
57
|
0
|
0
|
|
|
|
|
if ( defined $c1->utc_start_datetime ) { |
58
|
0
|
|
|
|
|
|
$utc_start = $c1->utc_start_datetime->utc_rd_as_seconds; |
59
|
0
|
|
|
|
|
|
$local_start = $c1->local_start_datetime->utc_rd_as_seconds; |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
else { |
62
|
0
|
|
|
|
|
|
$utc_start = $local_start = '-inf'; |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
0
|
|
|
|
|
|
my $utc_end = $c2->utc_start_datetime->utc_rd_as_seconds; |
66
|
0
|
|
|
|
|
|
my $local_end = $utc_end + $c1->total_offset; |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
return { |
69
|
0
|
|
|
|
|
|
utc_start => $utc_start, |
70
|
|
|
|
|
|
|
utc_end => $utc_end, |
71
|
|
|
|
|
|
|
local_start => $local_start, |
72
|
|
|
|
|
|
|
local_end => $local_end, |
73
|
|
|
|
|
|
|
short_name => $c1->short_name, |
74
|
|
|
|
|
|
|
offset => $c1->total_offset, |
75
|
|
|
|
|
|
|
is_dst => $c1->is_dst, |
76
|
|
|
|
|
|
|
}; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
## no critic (Subroutines::ProhibitUnusedPrivateSubroutines, InputOutput::RequireCheckedSyscalls) |
80
|
|
|
|
|
|
|
sub _debug_output { |
81
|
0
|
|
|
0
|
|
|
my $self = shift; |
82
|
|
|
|
|
|
|
|
83
|
0
|
|
|
|
|
|
my $obs = $self->observance; |
84
|
|
|
|
|
|
|
|
85
|
0
|
0
|
|
|
|
|
if ( $self->utc_start_datetime ) { |
86
|
0
|
|
|
|
|
|
print ' UTC: ', $self->utc_start_datetime->datetime, "\n"; |
87
|
0
|
|
|
|
|
|
print ' Local: ', $self->local_start_datetime->datetime, "\n"; |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
else { |
90
|
0
|
|
|
|
|
|
print " First change (starts at -inf)\n"; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
0
|
|
|
|
|
|
print ' Short name: ', $self->short_name, "\n"; |
94
|
0
|
|
|
|
|
|
printf " UTC offset: %s (%s)\n", $obs->offset_from_utc, |
95
|
|
|
|
|
|
|
$obs->offset_from_utc_as_hm; |
96
|
|
|
|
|
|
|
|
97
|
0
|
0
|
0
|
|
|
|
if ( $obs->offset_from_std || $self->rule ) { |
98
|
0
|
0
|
|
|
|
|
if ( $obs->offset_from_std ) { |
99
|
0
|
|
|
|
|
|
printf " Std offset: %s (%s)\n", $obs->offset_from_std, |
100
|
|
|
|
|
|
|
$obs->offset_from_std_as_hm; |
101
|
|
|
|
|
|
|
} |
102
|
|
|
|
|
|
|
|
103
|
0
|
0
|
|
|
|
|
if ( $self->rule ) { |
104
|
0
|
|
|
|
|
|
printf " Std offset: %s (%s) - %s rule\n", |
105
|
|
|
|
|
|
|
$self->rule->offset_from_std, |
106
|
|
|
|
|
|
|
$self->rule->offset_from_std_as_hm, |
107
|
|
|
|
|
|
|
$self->rule->name; |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
else { |
111
|
0
|
|
|
|
|
|
print " Std offset: 0 - no rule\n"; |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
0
|
|
|
|
|
|
print "\n"; |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
## use critic |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
1; |