package DateTime::TimeZone::OlsonDB;
use strict;
use vars qw( %MONTHS %DAYS $PLUS_ONE_DAY_DUR $MINUS_ONE_DAY_DUR );
use Params::Validate qw( validate SCALAR );
sub DEBUG () { 0 }
my $x = 1;
%MONTHS = map { $_ => $x++ }
qw( Jan Feb Mar Apr May Jun
Jul Aug Sep Oct Nov Dec);
$x = 1;
%DAYS = map { $_ => $x++ }
qw( Mon Tue Wed Thu Fri Sat Sun );
$PLUS_ONE_DAY_DUR = DateTime::Duration->new( days => 1 );
$MINUS_ONE_DAY_DUR = DateTime::Duration->new( days => -1 );
sub new
{
my $class = shift;
return bless { rules => {},
zones => {},
links => {},
}, $class;
}
sub parse_file
{
my $self = shift;
my $file = shift;
open my $fh, "<$file"
or die "Cannot read $file: $!";
while (<$fh>)
{
chomp;
$self->_parse_line($_);
}
}
sub _parse_line
{
my $self = shift;
my $line = shift;
return if $line =~ /^\s+$/;
return if $line =~ /^#/;
# remove any comments at the end of the line
$line =~ s/\s*#.+$//;
if ( $self->{in_zone} && $line =~ /^\t/ )
{
$self->_parse_zone( $line, $self->{in_zone} );
return;
}
foreach ( qw( Rule Zone Link ) )
{
if ( substr( $line, 0, 4 ) eq $_ )
{
my $m = '_parse_' . lc $_;
$self->$m($line);
}
}
}
sub _parse_rule
{
my $self = shift;
my $rule = shift;
my @items = split /\s+/, $rule, 10;
shift @items;
my $name = shift @items;
my %rule;
@rule{ qw( from to type in on at save letter ) } = @items;
delete $rule{letter} if $rule{letter} eq '-';
# As of the 2003a data, there are no rules with a type set
delete $rule{type} if $rule{type} eq '-';
push @{ $self->{rules}{$name} },
DateTime::TimeZone::OlsonDB::Rule->new( name => $name, %rule );
undef $self->{in_zone};
}
sub _parse_zone
{
my $self = shift;
=1= |