sub _generate_spans_until_match
{
my $self = shift;
my $generate_until_year = shift;
my $seconds = shift;
my $type = shift;
my @changes;
my @rules = @{ $self->_rules };
foreach my $year ( $self->{max_year} .. $generate_until_year )
{
for ( my $x = 0; $x < @rules; $x++ )
{
my $last_offset_from_std;
if ( @rules == 2 )
{
$last_offset_from_std =
$x ? $rules[0]->offset_from_std : $rules[1]->offset_from_std;
}
elsif ( @rules == 1 )
{
$last_offset_from_std = $rules[0]->offset_from_std;
}
else
{
my $count = scalar @rules;
die "Cannot generate future changes for zone with $count infinite rules\n";
}
my $rule = $rules[$x];
my $next =
$rule->utc_start_datetime_for_year
( $year, $self->{last_offset}, $last_offset_from_std );
# don't bother with changes we've seen already
next if $next->utc_rd_as_seconds < $self->max_span->[UTC_END];
push @changes,
DateTime::TimeZone::OlsonDB::Change->new
( type => 'rule',
utc_start_datetime => $next,
local_start_datetime =>
$next +
DateTime::Duration->new
( seconds => $self->{last_observance}->total_offset +
$rule->offset_from_std ),
short_name =>
sprintf( $self->{last_observance}->format, $rule->letter ),
observance => $self->{last_observance},
rule => $rule,
);
}
}
$self->{max_year} = $generate_until_year;
my @sorted = sort { $a->utc_start_datetime <=> $b->utc_start_datetime } @changes;
my ( $start, $end ) = _keys_for_type($type);
my $match;
for ( my $x = 1; $x < @sorted; $x++ )
{
my $last_total_offset =
$x == 1 ? $self->max_span->[OFFSET] : $sorted[ $x - 2 ]->total_offset;
my $span =
DateTime::TimeZone::OlsonDB::Change::two_changes_as_span
( @sorted[ $x - 1, $x ], $last_total_offset );
$span = _span_as_array($span);
push @{ $self->{spans} }, $span;
$match = $span
if $seconds >= $span->[$start] && $seconds < $span->[$end];
}
return $match;
}
sub max_span { $_[0]->{spans}[-1] }
sub _keys_for_type
{
$_[0] eq 'utc' ? ( UTC_START, UTC_END ) : ( LOCAL_START, LOCAL_END );
}
sub _span_as_array
{
[ @{ $_[0] }{ qw( utc_start utc_end local_start local_end offset is_dst short_name ) } ];
}
sub is_floating { 0 }
sub is_utc { 0 }
sub has_dst_changes { 0 }
=4= |