use strict;
use warnings;
use Test::More;
use Test::Fatal;
use DateTime;
undef $ENV{PERL_DATETIME_DEFAULT_TZ};
{
# Tests creating objects from epoch time
my $t1 = DateTime->from_epoch( epoch => 0 );
is( $t1->epoch, 0, 'epoch should be 0' );
is( $t1->second, 0, 'seconds are correct on epoch 0' );
is( $t1->minute, 0, 'minutes are correct on epoch 0' );
is( $t1->hour, 0, 'hours are correct on epoch 0' );
is( $t1->day, 1, 'days are correct on epoch 0' );
is( $t1->month, 1, 'months are correct on epoch 0' );
is( $t1->year, 1970, 'year is correct on epoch 0' );
is(
DateTime->from_epoch(0), $t1,
'passing one arg (0) to from_epoch returns expected result'
);
}
{
my $dt = DateTime->from_epoch( epoch => '3600' );
is(
$dt->epoch, 3600,
'creation test from epoch = 3600 (compare to epoch)'
);
}
{
# these tests could break if the time changed during the next three lines
my $now = time;
my $nowtest = DateTime->now();
my $nowtest2 = DateTime->from_epoch( epoch => $now );
is( $nowtest->hour, $nowtest2->hour, 'Hour: Create without args' );
is( $nowtest->month, $nowtest2->month, 'Month : Create without args' );
is( $nowtest->minute, $nowtest2->minute, 'Minute: Create without args' );
}
{
my $epochtest = DateTime->from_epoch( epoch => '997121000' );
is(
$epochtest->epoch, 997121000,
'epoch method returns correct value'
);
is( $epochtest->hour, 18, 'hour' );
is( $epochtest->min, 3, 'minute' );
is(
DateTime->from_epoch(997121000), $epochtest,
'passing one arg (997121000) to from_epoch returns expected result'
);
}
{
my $dt = DateTime->from_epoch( epoch => 3600 );
$dt->set_time_zone('+0100');
is( $dt->epoch, 3600, 'epoch is 3600' );
is( $dt->hour, 2, 'hour is 2' );
}
{
my $dt = DateTime->new(
year => 1970,
month => 1,
day => 1,
hour => 0,
time_zone => '-0100',
);
is( $dt->epoch, 3600, 'epoch is 3600' );
}
{
my $dt = DateTime->from_epoch(
epoch => 0,
time_zone => '-0100',
);
is( $dt->offset, -3600, 'offset should be -3600' );
is( $dt->epoch, 0, 'epoch is 0' );
}
# Adding/subtracting should affect epoch
{
my $expected = 1049160602;
my $epochtest = DateTime->from_epoch( epoch => $expected );
is(
$epochtest->epoch, $expected,
"epoch method returns correct value ($expected)"
);
is( $epochtest->hour, 1, 'hour' );
is( $epochtest->min, 30, 'minute' );
$epochtest->add( hours => 2 );
$expected += 2 * 60 * 60;
is( $epochtest->hour, 3, 'adjusted hour' );
is(
$epochtest->epoch, $expected,
"epoch method returns correct adjusted value ($expected)"
);
}
{
my $dt = DateTime->from_epoch( epoch => 0.5 );
is(
$dt->nanosecond, 500_000_000,
'nanosecond should be 500,000,000 with 0.5 as epoch'
);
is( $dt->epoch, 0, 'epoch should be 0' );
is( $dt->hires_epoch, 0.5, 'hires_epoch should be 0.5' );
}
{
my $dt = DateTime->from_epoch( epoch => -0.5 );
is(
$dt->nanosecond, 500_000_000,
'nanosecond should be 500,000,000 with -0.5 as epoch'
);
is( $dt->epoch, -1, 'epoch should be -1' );
is( $dt->hires_epoch, -0.5, 'hires_epoch should be -0.5' );
}
{
my $dt = DateTime->from_epoch( epoch => 1609459199.999999 );
is(
$dt->nanosecond, 999999000,
'nanosecond should be 999,999,000 with 1609459199.999999 as epoch'
);
is( $dt->epoch, 1609459199, 'epoch should be 1609459199' );
}
{
my $dt = DateTime->from_epoch( epoch => 0.1234567891 );
is(
$dt->nanosecond, 123_457_000,
'nanosecond should be rounded to 123,457,000 when given 0.1234567891'
);
}
{
my $dt = DateTime->from_epoch( epoch => -0.1234567891 );
is(
$dt->nanosecond, 876_543_000,
'nanosecond should be rounded to 876,543,000 when given -0.1234567891'
);
}
{
is(
DateTime->new( year => 1904 )->epoch, -2082844800,
'epoch should work back to at least 1904'
);
my $dt = DateTime->from_epoch( epoch => -2082844800 );
is( $dt->year, 1904, 'year should be 1904' );
is( $dt->month, 1, 'month should be 1904' );
is( $dt->day, 1, 'day should be 1904' );
}
{
for my $pair (
[ 1 => -62135596800 ],
[ 99 => -59042995200 ],
[ 100 => -59011459200 ],
[ 999 => -30641760000 ],
) {
my ( $year, $epoch ) = @{$pair};
is(
DateTime->new( year => $year )->epoch, $epoch,
"epoch for $year is $epoch"
);
}
}
{
package Number::Overloaded;
use overload
'0+' => sub { $_[0]->{num} },
fallback => 1;
sub new { bless { num => $_[1] }, $_[0] }
}
{
my $time = Number::Overloaded->new(12345);
my $dt = DateTime->from_epoch( epoch => $time );
is( $dt->epoch, 12345, 'can pass overloaded object to from_epoch' );
$time = Number::Overloaded->new(12345.1234);
$dt = DateTime->from_epoch( epoch => $time );
is( $dt->epoch, 12345, 'decimal epoch in overloaded object' );
is(
DateTime->from_epoch($time), $dt,
'passing one arg (object with number overload) to from_epoch returns expected result'
);
}
{
my $time = Number::Overloaded->new(-12345);
my $dt = DateTime->from_epoch( epoch => $time );
is( $dt->epoch, -12345, 'negative epoch in overloaded object' );
}
{
my @tests = (
'asldkjlkjd',
'1234 foo',
'adlkj 1234',
);
for my $test (@tests) {
like(
exception { DateTime->from_epoch( epoch => $test ) },
qr/Validation failed for type named Num/,
qq{'$test' is not a valid epoch value}
);
}
}
done_testing();