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