1 package DateTime::TimeZone::OlsonDB::Change;
6 use Params::Validate qw( validate SCALAR UNDEF OBJECT );
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)$/ },
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' )
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;
35 $p{offset_from_std} = $p{observance}->offset_from_std;
36 $p{offset_from_std} = $p{rule}->offset_from_std if defined $p{rule};
39 $p{offset_from_utc} = $p{observance}->offset_from_utc;
42 $p{is_dst} = 1 if $p{rule} && $p{rule}->offset_from_std;
43 $p{is_dst} = 1 if $p{observance}->offset_from_std;
45 if ( $p{short_name} =~ m{(\w+)/(\w+)} )
47 $p{short_name} = $p{is_dst} ? $2 : $1;
50 return bless \%p, $class;
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 }
63 sub two_changes_as_span
65 my ( $c1, $c2, $last_total_offset ) = @_;
67 my ( $utc_start, $local_start );
69 if ( defined $c1->utc_start_datetime )
71 $utc_start = $c1->utc_start_datetime->utc_rd_as_seconds;
72 $local_start = $c1->local_start_datetime->utc_rd_as_seconds;
76 $utc_start = $local_start = '-inf';
79 my $utc_end = $c2->utc_start_datetime->utc_rd_as_seconds;
80 my $local_end = $utc_end + $c1->total_offset;
82 return { utc_start => $utc_start,
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,
96 my $obs = $self->observance;
98 if ( $self->utc_start_datetime )
100 print " UTC: ", $self->utc_start_datetime->datetime, "\n";
101 print " Local: ", $self->local_start_datetime->datetime, "\n";
105 print " First change (starts at -inf)\n";
108 print " Short name: ", $self->short_name, "\n";
109 print " UTC offset: ", $obs->offset_from_utc, "\n";
111 if ( $obs->offset_from_std || $self->rule )
113 if ( $obs->offset_from_std )
115 print " Std offset: ", $obs->offset_from_std, "\n";
120 print " Std offset: ", $self->rule->offset_from_std, ' - ',
121 $self->rule->name, " rule\n";
126 print " Std offset: 0 - no rule\n";