undef
$ENV
{PERL_DATETIME_DEFAULT_TZ};
{
my
$dt1
= DateTime->new(
year
=> 2003,
month
=> 5,
day
=> 6,
time_zone
=>
'America/Chicago'
,
);
my
$dt2
= DateTime->new(
year
=> 2003,
month
=> 11,
day
=> 6,
time_zone
=>
'America/Chicago'
,
);
my
$dur1
=
$dt2
->subtract_datetime(
$dt1
);
my
%deltas1
=
$dur1
->deltas;
is(
$deltas1
{months}, 6,
'delta_months is 6'
);
is(
$deltas1
{days}, 0,
'delta_days is 0'
);
is(
$deltas1
{minutes}, 0,
'delta_minutes is 0'
);
is(
$deltas1
{seconds}, 0,
'delta_seconds is 0'
);
is(
DateTime->compare(
$dt1
->clone->add_duration(
$dur1
),
$dt2
), 0,
'subtract_datetime is reversible from start point'
);
is(
DateTime->compare(
$dt2
->clone->subtract_duration(
$dur1
),
$dt1
), 0,
'subtract_datetime is reversible from end point'
);
is(
$deltas1
{nanoseconds}, 0,
'delta_nanoseconds is 0'
);
my
$dur2
=
$dt1
->subtract_datetime(
$dt2
);
my
%deltas2
=
$dur2
->deltas;
is(
$deltas2
{months}, -6,
'delta_months is -6'
);
is(
$deltas2
{days}, 0,
'delta_days is 0'
);
is(
$deltas2
{minutes}, 0,
'delta_minutes is 0'
);
is(
$deltas2
{seconds}, 0,
'delta_seconds is 0'
);
is(
$deltas2
{nanoseconds}, 0,
'delta_nanoseconds is 0'
);
my
$dur3
=
$dt2
->delta_md(
$dt1
);
my
%deltas3
=
$dur3
->deltas;
is(
$deltas3
{months}, 6,
'delta_months is 6'
);
is(
$deltas3
{days}, 0,
'delta_days is 0'
);
is(
$deltas3
{minutes}, 0,
'delta_minutes is 0'
);
is(
$deltas3
{seconds}, 0,
'delta_seconds is 0'
);
is(
$deltas3
{nanoseconds}, 0,
'delta_nanoseconds is 0'
);
is(
DateTime->compare(
$dt1
->clone->add_duration(
$dur3
),
$dt2
), 0,
'delta_md is reversible from start point'
);
is(
DateTime->compare(
$dt2
->clone->subtract_duration(
$dur3
),
$dt1
), 0,
'delta_md is reversible from end point'
);
my
$dur4
=
$dt2
->delta_days(
$dt1
);
my
%deltas4
=
$dur4
->deltas;
is(
$deltas4
{months}, 0,
'delta_months is 0'
);
is(
$deltas4
{days}, 184,
'delta_days is 184'
);
is(
$deltas4
{minutes}, 0,
'delta_minutes is 0'
);
is(
$deltas4
{seconds}, 0,
'delta_seconds is 0'
);
is(
$deltas4
{nanoseconds}, 0,
'delta_nanoseconds is 0'
);
is(
DateTime->compare(
$dt1
->clone->add_duration(
$dur3
),
$dt2
), 0,
'delta_days is reversible from start point'
);
is(
DateTime->compare(
$dt2
->clone->subtract_duration(
$dur4
),
$dt1
), 0,
'delta_days is reversible from end point'
);
}
{
my
$dt1
= DateTime->new(
year
=> 2003,
month
=> 5,
day
=> 6,
hour
=> 18,
time_zone
=>
'America/Chicago'
,
);
my
$dt2
= DateTime->new(
year
=> 2003,
month
=> 11,
day
=> 6,
hour
=> 18,
time_zone
=>
'America/Chicago'
,
);
my
$dur1
=
$dt2
->subtract_datetime(
$dt1
);
my
%deltas1
=
$dur1
->deltas;
is(
$deltas1
{months}, 6,
'delta_months is 6'
);
is(
$deltas1
{days}, 0,
'delta_days is 0'
);
is(
$deltas1
{minutes}, 0,
'delta_minutes is 0'
);
is(
$deltas1
{seconds}, 0,
'delta_seconds is 0'
);
is(
$deltas1
{nanoseconds}, 0,
'delta_nanoseconds is 0'
);
}
{
my
$dt1
= DateTime->new(
year
=> 2003,
month
=> 11,
day
=> 6,
time_zone
=>
'America/Chicago'
,
);
my
$dt2
= DateTime->new(
year
=> 2004,
month
=> 5,
day
=> 6,
time_zone
=>
'America/Chicago'
,
);
my
$dur1
=
$dt2
->delta_md(
$dt1
);
my
%deltas1
=
$dur1
->deltas;
is(
$deltas1
{months}, 6,
'delta_months is 6'
);
is(
$deltas1
{days}, 0,
'delta_days is 0'
);
is(
$deltas1
{minutes}, 0,
'delta_minutes is 0'
);
is(
$deltas1
{seconds}, 0,
'delta_seconds is 0'
);
is(
$deltas1
{nanoseconds}, 0,
'delta_nanoseconds is 0'
);
my
$dur2
=
$dt2
->delta_days(
$dt1
);
my
%deltas2
=
$dur2
->deltas;
is(
$deltas2
{months}, 0,
'delta_months is 0'
);
is(
$deltas2
{days}, 182,
'delta_days is 182'
);
is(
$deltas2
{minutes}, 0,
'delta_minutes is 0'
);
is(
$deltas2
{seconds}, 0,
'delta_seconds is 0'
);
is(
$deltas2
{nanoseconds}, 0,
'delta_nanoseconds is 0'
);
}
{
my
$dt1
= DateTime->new(
year
=> 2003,
month
=> 5,
day
=> 6,
time_zone
=>
'America/Chicago'
,
);
my
$dt2
= DateTime->new(
year
=> 2003,
month
=> 11,
day
=> 6,
time_zone
=>
'America/Chicago'
,
);
$dt1
->set_time_zone(
'UTC'
);
$dt2
->set_time_zone(
'UTC'
);
my
$dur
=
$dt2
->subtract_datetime(
$dt1
);
is(
DateTime->compare(
$dt1
->add_duration(
$dur
),
$dt2
), 0,
'subtraction is reversible from start point with UTC'
);
is(
DateTime->compare(
$dt2
->subtract_duration(
$dur
),
$dt2
), 0,
'subtraction is reversible from start point with UTC'
);
}
{
my
$dt1
= DateTime->new(
year
=> 2003,
month
=> 5,
day
=> 6,
time_zone
=>
'America/Chicago'
,
);
my
$dt2
= DateTime->new(
year
=> 2003,
month
=> 11,
day
=> 6,
time_zone
=>
'America/Chicago'
,
);
my
$dur1
=
$dt2
->subtract_datetime_absolute(
$dt1
);
my
%deltas1
=
$dur1
->deltas;
is(
$deltas1
{months}, 0,
'delta_months is 0'
);
is(
$deltas1
{days}, 0,
'delta_days is 0'
);
is(
$deltas1
{minutes}, 0,
'delta_minutes is 0'
);
is(
$deltas1
{seconds}, 15901200,
'delta_seconds is 15901200'
);
is(
$deltas1
{nanoseconds}, 0,
'delta_nanoseconds is 0'
);
is(
DateTime->compare(
$dt1
->clone->add_duration(
$dur1
),
$dt2
), 0,
'subtraction is reversible'
);
is(
DateTime->compare(
$dt2
->clone->subtract_duration(
$dur1
),
$dt1
), 0,
'subtraction is doubly reversible'
);
my
$dur2
=
$dt1
->subtract_datetime_absolute(
$dt2
);
my
%deltas2
=
$dur2
->deltas;
is(
$deltas2
{months}, 0,
'delta_months is 0'
);
is(
$deltas2
{days}, 0,
'delta_days is 0'
);
is(
$deltas2
{minutes}, 0,
'delta_minutes is 0'
);
is(
$deltas2
{seconds}, -15901200,
'delta_seconds is -15901200'
);
is(
$deltas2
{nanoseconds}, 0,
'delta_nanoseconds is 0'
);
is(
DateTime->compare(
$dt2
->clone->add_duration(
$dur2
),
$dt1
), 0,
'subtraction is reversible'
);
is(
DateTime->compare(
$dt1
->clone->subtract_duration(
$dur2
),
$dt2
), 0,
'subtraction is doubly reversible'
);
}
{
my
$dt1
= DateTime->new(
year
=> 2003,
month
=> 4,
day
=> 6,
hour
=> 1,
minute
=> 58,
time_zone
=>
'America/Chicago'
,
);
my
$dt2
= DateTime->new(
year
=> 2003,
month
=> 4,
day
=> 6,
hour
=> 3,
minute
=> 1,
time_zone
=>
'America/Chicago'
,
);
my
$dur
=
$dt2
->subtract_datetime(
$dt1
);
my
%deltas
=
$dur
->deltas;
is(
$deltas
{months}, 0,
'delta_months is 0'
);
is(
$deltas
{days}, 0,
'delta_days is 0'
);
is(
$deltas
{minutes}, 3,
'delta_minutes is 3'
);
is(
$deltas
{seconds}, 0,
'delta_seconds is 0'
);
is(
$deltas
{nanoseconds}, 0,
'delta_nanoseconds is 0'
);
is(
DateTime->compare(
$dt1
->clone->add_duration(
$dur
),
$dt2
), 0,
'subtraction is reversible'
);
is(
DateTime->compare(
$dt2
->clone->subtract_duration(
$dur
),
$dt1
), 0,
'subtraction is doubly reversible'
);
}
{
my
$dt1
= DateTime->new(
year
=> 2003,
month
=> 4,
day
=> 5,
hour
=> 1,
minute
=> 58,
time_zone
=>
'America/Chicago'
,
);
my
$dt2
= DateTime->new(
year
=> 2003,
month
=> 4,
day
=> 6,
hour
=> 3,
minute
=> 1,
time_zone
=>
'America/Chicago'
,
);
my
$dur
=
$dt2
->subtract_datetime(
$dt1
);
my
%deltas
=
$dur
->deltas;
is(
$deltas
{months}, 0,
'delta_months is 0'
);
is(
$deltas
{days}, 1,
'delta_days is 1'
);
is(
$deltas
{minutes}, 3,
'delta_minutes is 3'
);
is(
$deltas
{seconds}, 0,
'delta_seconds is 0'
);
is(
$deltas
{nanoseconds}, 0,
'delta_nanoseconds is 0'
);
is(
DateTime->compare(
$dt1
->clone->add_duration(
$dur
),
$dt2
), 0,
'dt1 + dur = dt2'
);
is(
DateTime->compare(
$dt2
->clone->subtract_duration(
$dur
),
$dt1
->clone->add(
hours
=> 1 )
),
0,
'dt2 - dur != dt1 (not reversible)'
);
is(
DateTime->compare(
$dt2
->clone->subtract_duration(
$dur
->clock_duration )
->subtract_duration(
$dur
->calendar_duration ),
$dt1
),
0,
'dt2 - dur->clock - dur->cal = dt1 (reversible when componentized)'
);
my
$dur2
=
$dt1
->subtract_datetime(
$dt2
);
my
%deltas2
=
$dur2
->deltas;
is(
$deltas2
{months}, 0,
'delta_months is 0'
);
is(
$deltas2
{days}, -1,
'delta_days is 1'
);
is(
$deltas2
{minutes}, -3,
'delta_minutes is 3'
);
is(
$deltas2
{seconds}, 0,
'delta_seconds is 0'
);
is(
$deltas2
{nanoseconds}, 0,
'delta_nanoseconds is 0'
);
is(
$dt2
->clone->add_duration(
$dur2
)->datetime,
'2003-04-05T02:58:00'
,
'dt2 + dur2 != dt1'
);
is(
DateTime->compare(
$dt2
->clone->add_duration(
$dur2
->clock_duration )
->add_duration(
$dur2
->calendar_duration ),
$dt1
),
0,
'dt2 + dur2->clock + dur2->cal = dt1'
);
is(
DateTime->compare(
$dt1
->clone->subtract_duration(
$dur2
),
$dt2
), 0,
'dt1 - dur2 = dt2'
);
}
{
my
$dt1
= DateTime->new(
year
=> 2003,
month
=> 4,
day
=> 6,
hour
=> 3,
minute
=> 1,
time_zone
=>
'America/Chicago'
,
);
my
$dt2
= DateTime->new(
year
=> 2003,
month
=> 4,
day
=> 7,
hour
=> 3,
minute
=> 2,
time_zone
=>
'America/Chicago'
,
);
my
$dur
=
$dt2
->subtract_datetime(
$dt1
);
my
%deltas
=
$dur
->deltas;
is(
$deltas
{months}, 0,
'delta_months is 0'
);
is(
$deltas
{days}, 1,
'delta_days is 1'
);
is(
$deltas
{minutes}, 1,
'delta_minutes is 1'
);
is(
$deltas
{seconds}, 0,
'delta_seconds is 0'
);
is(
$deltas
{nanoseconds}, 0,
'delta_nanoseconds is 0'
);
my
$dur2
=
$dt1
->subtract_datetime(
$dt2
);
my
%deltas2
=
$dur2
->deltas;
is(
$deltas2
{months}, 0,
'delta_months is 0'
);
is(
$deltas2
{days}, -1,
'delta_days is -1'
);
is(
$deltas2
{minutes}, -1,
'delta_minutes is -1'
);
is(
$deltas2
{seconds}, 0,
'delta_seconds is 0'
);
is(
$deltas2
{nanoseconds}, 0,
'delta_nanoseconds is 0'
);
}
{
my
$dt1
= DateTime->new(
year
=> 2003,
month
=> 4,
day
=> 5,
hour
=> 1,
minute
=> 58,
time_zone
=>
'America/Chicago'
,
);
my
$dt2
= DateTime->new(
year
=> 2003,
month
=> 4,
day
=> 7,
hour
=> 2,
minute
=> 1,
time_zone
=>
'America/Chicago'
,
);
my
$dur
=
$dt2
->subtract_datetime(
$dt1
);
my
%deltas
=
$dur
->deltas;
is(
$deltas
{months}, 0,
'delta_months is 0'
);
is(
$deltas
{days}, 2,
'delta_days is 2'
);
is(
$deltas
{minutes}, 3,
'delta_minutes is 3'
);
is(
$deltas
{seconds}, 0,
'delta_seconds is 0'
);
is(
$deltas
{nanoseconds}, 0,
'delta_nanoseconds is 0'
);
is(
DateTime->compare(
$dt1
->clone->add_duration(
$dur
),
$dt2
), 0,
'subtraction is reversible'
);
is(
DateTime->compare(
$dt2
->clone->subtract_duration(
$dur
),
$dt1
), 0,
'subtraction is doubly reversible'
);
}
{
my
$dt1
= DateTime->new(
year
=> 2003,
month
=> 5,
day
=> 6,
time_zone
=>
'America/Chicago'
,
);
my
$dt2
= DateTime->new(
year
=> 2003,
month
=> 11,
day
=> 6,
time_zone
=>
'America/Chicago'
,
);
$dt1
->set_time_zone(
'floating'
);
$dt2
->set_time_zone(
'floating'
);
my
$dur
=
$dt2
->subtract_datetime(
$dt1
);
my
%deltas
=
$dur
->deltas;
is(
$deltas
{months}, 6,
'delta_months is 6'
);
is(
$deltas
{days}, 0,
'delta_days is 0'
);
is(
$deltas
{minutes}, 0,
'delta_minutes is 0'
);
is(
$deltas
{seconds}, 0,
'delta_seconds is 0'
);
is(
$deltas
{nanoseconds}, 0,
'delta_nanoseconds is 0'
);
is(
DateTime->compare(
$dt1
->clone->add_duration(
$dur
),
$dt2
), 0,
'subtraction is reversible from start point'
);
is(
DateTime->compare(
$dt2
->clone->subtract_duration(
$dur
),
$dt1
), 0,
'subtraction is reversible from end point'
);
}
{
my
$dt1
= DateTime->new(
year
=> 2005,
month
=> 8,
time_zone
=>
'Europe/London'
,
);
my
$dt2
= DateTime->new(
year
=> 2005,
month
=> 11,
time_zone
=>
'Europe/London'
,
);
my
$dur
=
$dt2
->subtract_datetime(
$dt1
);
my
%deltas
=
$dur
->deltas;
is(
$deltas
{months}, 3,
'3 months between two local times over DST change'
);
is(
$deltas
{days}, 0,
'0 days between two local times over DST change'
);
is(
$deltas
{minutes}, 0,
'0 minutes between two local times over DST change'
);
}
{
my
$dt1
= DateTime->new(
year
=> 2005,
month
=> 8,
hour
=> 12,
time_zone
=>
'Europe/London'
,
);
my
$dt2
= DateTime->new(
year
=> 2005,
month
=> 11,
hour
=> 12,
time_zone
=>
'Europe/London'
,
);
my
$dur
=
$dt2
->subtract_datetime(
$dt1
);
my
%deltas
=
$dur
->deltas;
is(
$deltas
{months}, 3,
'3 months between two local times over DST change'
);
is(
$deltas
{days}, 0,
'0 days between two local times over DST change'
);
is(
$deltas
{minutes}, 0,
'0 minutes between two local times over DST change'
);
}
{
my
$dt2
= DateTime->new(
year
=> 2003,
month
=> 10,
day
=> 26,
hour
=> 1,
time_zone
=>
'America/Chicago'
,
);
my
$dt1
=
$dt2
->clone->subtract(
hours
=> 1 );
my
$dur
=
$dt2
->subtract_datetime(
$dt1
);
my
%deltas
=
$dur
->deltas;
is(
$deltas
{months}, 0,
'0 months between two local times over DST change'
);
is(
$deltas
{days}, 0,
'0 days between two local times over DST change'
);
is(
$deltas
{minutes}, 60,
'60 minutes between two local times over DST change'
);
is(
DateTime->compare(
$dt1
->clone->add_duration(
$dur
),
$dt2
), 0,
'subtraction is reversible'
);
is(
DateTime->compare(
$dt2
->clone->subtract_duration(
$dur
),
$dt1
), 0,
'subtraction is doubly reversible'
);
}
{
my
$dt1
= DateTime->new(
year
=> 2003,
month
=> 5,
day
=> 6,
time_zone
=>
'America/New_York'
,
);
my
$dt2
= DateTime->new(
year
=> 2003,
month
=> 5,
day
=> 6,
time_zone
=>
'America/Chicago'
,
);
my
$dur
=
$dt2
->subtract_datetime(
$dt1
);
my
%deltas
=
$dur
->deltas;
is(
$deltas
{months}, 0,
'0 months between two local times over DST change'
);
is(
$deltas
{days}, 0,
'0 days between two local times over DST change'
);
is(
$deltas
{minutes}, 60,
'60 minutes between two local times over DST change'
);
is(
DateTime->compare(
$dt1
->clone->add_duration(
$dur
),
$dt2
), 0,
'subtraction is reversible'
);
is(
DateTime->compare(
$dt2
->clone->subtract_duration(
$dur
),
$dt1
), 0,
'subtraction is doubly reversible'
);
}
{
my
$dt1
= DateTime->new(
year
=> 2005,
month
=> 4,
day
=> 3,
hour
=> 7,
minute
=> 0,
time_zone
=>
'America/New_York'
);
my
$dt2
= DateTime->new(
year
=> 2005,
month
=> 4,
day
=> 3,
hour
=> 8,
minute
=> 0,
time_zone
=>
'America/New_York'
);
my
$dur
=
$dt2
->subtract_datetime(
$dt1
);
my
(
$minutes
,
$seconds
) =
$dur
->in_units(
'minutes'
,
'seconds'
);
is(
$minutes
, 60,
'subtraction of two dates on a DST change date, minutes == 60'
);
is(
$seconds
, 0,
'subtraction of two dates on a DST change date, seconds == 0'
);
$dur
=
$dt1
->subtract_datetime(
$dt1
);
ok(
$dur
->is_zero,
'dst change date (no dst) - itself, duration is zero'
);
}
{
my
$dt1
= DateTime->new(
year
=> 2005,
month
=> 4,
day
=> 3,
hour
=> 1,
minute
=> 0,
time_zone
=>
'America/New_York'
);
my
$dur
=
$dt1
->subtract_datetime(
$dt1
);
ok(
$dur
->is_zero,
'dst change date (with dst) - itself, duration is zero'
);
}
{
my
$dt1
= DateTime->new(
year
=> 2009,
month
=> 3,
day
=> 9,
time_zone
=>
'America/New_York'
);
my
$dt2
= DateTime->new(
year
=> 2009,
month
=> 3,
day
=> 9,
time_zone
=>
'Asia/Hong_Kong'
);
my
$dur
=
$dt1
->subtract_datetime(
$dt2
);
is(
$dur
->delta_minutes, 720,
'subtraction the day after a DST change in one zone, where the other datetime is in a different zone'
);
}
{
my
$dt1
= DateTime->new(
year
=> 2009,
month
=> 3,
day
=> 8,
hour
=> 1,
time_zone
=>
'America/New_York'
);
my
$dt2
= DateTime->new(
year
=> 2009,
month
=> 3,
day
=> 8,
hour
=> 1,
time_zone
=>
'Asia/Hong_Kong'
);
my
$dur
=
$dt1
->subtract_datetime(
$dt2
);
is(
$dur
->delta_minutes, 780,
'subtraction the day of a DST change in one zone (before the change),'
.
' where the other datetime is in a different zone'
);
}
{
my
$dt1
= DateTime->new(
year
=> 2009,
month
=> 3,
day
=> 8,
hour
=> 4,
time_zone
=>
'America/New_York'
);
my
$dt2
= DateTime->new(
year
=> 2009,
month
=> 3,
day
=> 8,
hour
=> 4,
time_zone
=>
'Asia/Hong_Kong'
);
my
$dur
=
$dt1
->subtract_datetime(
$dt2
);
is(
$dur
->delta_minutes, 720,
'subtraction the day of a DST change in one zone (after the change),'
.
' where the other datetime is in a different zone'
);
}
done_testing();