Skip to content

DateTime->from_object, DateTime::Format::Epoch, and leap seconds #104

@esabol

Description

@esabol

Hi, I'm using DateTime::Format::Epoch to parse values in seconds since 1980-01-06 00:00:00 UTC. Everything works great unless the value for the time coincides with a leap second. One second less, it works. One second more, it works. For the leap second itself, I get the following error:

Validation failed for type named Hour declared in package DateTime::Types (/usr1/local/perl5/5.28.0/lib/site_perl/5.28.0/x86_64-linux/DateTime/Types.pm) at line 101 in sub named (eval) with value 24

Trace begun at Specio::Exception->new line 57
Specio::Exception::throw('Specio::Exception', 'message', 'Validation failed for type named Hour declared in package DateTime::Types (/usr1/local/perl5/5.28.0/lib/site_perl/5.28.0/x86_64-linux/DateTime/Types.pm) at line 101 in sub named (eval) with value 24', 'type', 'Specio::Constraint::Simple=HASH(0x271c540)', 'value', 24) called at (eval 220) line 144
DateTime::_check_new_params('second', 0, 'hour', 24, 'month', 6, 'day', 30, 'year', 2012, 'nanosecond', 0, 'minute', 0, 'time_zone', 'UTC') called at /usr1/local/perl5/5.28.0/lib/site_perl/5.28.0/x86_64-linux/DateTime.pm line 176
DateTime::new('DateTime', 'second', 0, 'hour', 24, 'month', 6, 'day', 30, 'year', 2012, 'nanosecond', 0, 'minute', 0, 'time_zone', 'UTC') called at /usr1/local/perl5/5.28.0/lib/site_perl/5.28.0/x86_64-linux/DateTime.pm line 611
DateTime::from_object('DateTime', 'object', 'DateTime::Format::Epoch::_DateTime=HASH(0x1a32888)') called at /usr1/local/perl5/5.28.0/lib/site_perl/5.28.0/DateTime/Format/Epoch.pm line 183
DateTime::Format::Epoch::parse_datetime('DateTime::Format::Epoch=HASH(0x2ef4cf8)', 1025136015) called at /path/to/test.pl line 60

Under the hood, DateTime::Format::Epoch is executing:

    my $temp_dt = bless { rd_days => $rd_days, rd_secs => $rd_secs},
                        'DateTime::Format::Epoch::_DateTime';

    my $dt = $self->{epoch_class}->from_object( object => $temp_dt );

In this specific case, $rd_days is 734684 and $rd_secs => 86400 and $self->{epoch_class} is "DateTime". DateTime::LeapSecond::day_length( 734684 ) returns 86401. The DateTime::Format::Epoch::_DateTime class only has one method: utc_rd_values.

Here's my code:

use DateTime;
use DateTime::TimeZone;
use DateTime::Format::Epoch;

my $utc = DateTime::TimeZone->new(name => 'Etc/UTC');

my $gps_epoch = DateTime->new(year => 1980, month => 1, day => 6,
                              hour => 0, minute => 0, second => 0,
                              time_zone => $utc); # 1980-01-06 00:00:00 UTC

my $gps_parser = DateTime::Format::Epoch->new(epoch => $gps_epoch,
                                              dhms => 0,
                                              start_at => 0,
                                              unit => 'seconds',
                                              type => 'float',
                                              skip_leap_seconds => 0);

print "DateTime $DateTime::VERSION\n";
print "DateTime::LeapSecond $DateTime::LeapSecond::VERSION\n";
print "DateTime::Format::Epoch $DateTime::Format::Epoch::VERSION\n";
my $date = '1025136015';
print "date: $date\n";
my $dt = $gps_parser->parse_datetime($date);
print "dt: $dt\n";
print "tz: ",$dt->time_zone,"\n";

Versions:

DateTime 1.52
DateTime::LeapSecond 1.52
DateTime::Format::Epoch 0.16

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions