view release on metacpan or search on metacpan
0.30    2005-12-22
[ ENHANCEMENTS ]
- Expanded and rewrote the docs on date math to try to explain exactly
  how DateTime.pm works, and in particular cover the problems DST
  introduces to various types of date math.  The docs now also include
  some specific recommendations on getting sane results from datetime
  math.
- Added calendar_duration() and clock_duration() methods to
  DateTime::Duration
- Explicitly override the stringification method for
  DateTime::Infinite objects.  They now stringify as whatever the IEEE
  infinity and negative infinity numbers stringify to on your
  platform.  On Linux this is "inf" and "-inf". CPAN RT #16632.
[ BUG FIXES ]
- delta_md() and delta_days() did not always return correct values
  The subtract_datetime_absolute method returns results similar to
  what was previously returned from subtract_datetime.
  Thanks to Matthew McGillis for bringing this up, and Joshua Hoblitt
  and Eugene van der Pijll for contributing to the ensuing discussion.
[ IMPROVEMENTS ]
- DateTime.pm compare() method is now documented to work with any
  other calendar class that provides a utc_rd_values() method.
- Added the subtract_datetime_absolute method.  See the docs for
  details.
- Documented the inverse() method in DateTime::Duration.
0.1601  2003-08-07
[ BUG FIXES ]
0.07     2003-02-26
[IMPROVEMENTS]
- Added a small hack to the compare() method so that this module can
  be used with Set::Infinite.
- Changed compare so that it can be used to compare two objects from
  different calendars that conform to the DateTime::Calendar
  interface.
- Added explanation of exactly what calendar this module represents
  ("proleptic Gregorian calendar") to docs.
- Added a Spanish language DateTime::Language subclass.  Implemented
  by Flavio S. Glock.
- Added support for specifying a language by ISO code ("en" or
  "pt-br") as well as the subclass name.  Based on a patch from Eric
  Cholet.
- Revamped the externally visible DateTime::Language API.
- It is no longer possible to directly instantiate a
  DateTime::Language subclass, instead use:
    my $en = DateTime::Language->new( language => 'English' );
- The from_object() method no longer accepts a "time_zone" parameter.
0.06     2003-02-16
- The docs said that there was no year 0 in the Gregorian calendar,
  but that was wrong.  The year() method can now return 0.  The
  year_0() method has been removed.
- Added jd() and mjd() methods.
- Re-implemented some of the core code in XS for speed.
0.05     2003-02-13
- Fix handling and reporting of epoch times.  Epoch times are, by
    $dt->set_time_zone('America/Chicago');
    $dt->set_formatter($formatter);
# DESCRIPTION
DateTime is a class for the representation of date/time combinations, and is
part of the Perl DateTime project.
It represents the Gregorian calendar, extended backwards in time before its
creation (in 1582). This is sometimes known as the "proleptic Gregorian
calendar". In this calendar, the first day of the calendar (the epoch), is the
first day of year 1, which corresponds to the date which was (incorrectly)
believed to be the birth of Jesus Christ.
The calendar represented does have a year 0, and in that way differs from how
dates are often written using "BCE/CE" or "BC/AD".
For infinite datetimes, please see the [DateTime::Infinite](https://metacpan.org/pod/DateTime%3A%3AInfinite)
module.
# USAGE
## 0-based Versus 1-based Numbers
The `DateTime` module follows a simple logic for determining whether or not a
This constructor takes the same arguments as can be given to the `new` method,
except that it does not accept a `month` or `day` argument. Instead, it
requires both `year` and `day_of_year`. The day of year must be between 1 and
366, and 366 is only allowed for leap years.
### DateTime->from\_object( object => $object, ... )
This class method can be used to construct a new DateTime object from any
object that implements the `utc_rd_values` method. All `DateTime::Calendar`
modules must implement this method in order to provide cross-calendar
compatibility. This method accepts a `locale` and `formatter` parameter
If the object passed to this method has a `time_zone` method, that is used to
set the time zone of the newly created `DateTime` object.
Otherwise, the returned object will be in the floating time zone.
### $dt->clone
This object method returns a new object that is replica of the object upon
This method returns the number of days in the current quarter.
### $dt->year\_length
This method returns the number of days in the current year.
### $dt->week
    my ( $week_year, $week_number ) = $dt->week;
Returns information about the calendar week for the date. The values returned
by this method are also available separately through the `$dt->week_year`
and `$dt->week_number` methods.
The first week of the year is defined by ISO as the one which contains the
fourth day of January, which is equivalent to saying that it's the first week
to overlap the new year by at least four days.
Typically the week year will be the same as the year that the object is in, but
dates at the very beginning of a calendar year often end up in the last week of
the prior year, and similarly, the final few days of the year may be placed in
the first week of the next year.
### $dt->week\_year
Returns the year of the week. See `$dt->week` for details.
### $dt->week\_number
Returns the week of the year, from 1..53. See `$dt->week` for details.
`1325376000` returns `1325376000`.
### $dt->is\_finite, $dt->is\_infinite
These methods allow you to distinguish normal datetime objects from infinite
ones. Infinite datetime objects are documented in [DateTime::Infinite](https://metacpan.org/pod/DateTime%3A%3AInfinite).
### $dt->utc\_rd\_values
Returns the current UTC Rata Die days, seconds, and nanoseconds as a three
element list. This exists primarily to allow other calendar modules to create
objects based on the values provided by this object.
### $dt->local\_rd\_values
Returns the current local Rata Die days, seconds, and nanoseconds as a three
element list. This exists for the benefit of other modules which might want to
use this information for date math, such as [DateTime::Event::Recurrence](https://metacpan.org/pod/DateTime%3A%3AEvent%3A%3ARecurrence).
### $dt->leap\_seconds
UTC times.
Since DateTime objects overload comparison operators, this:
    @dates = sort @dates;
is equivalent to this:
    @dates = sort { DateTime->compare( $a, $b ) } @dates;
DateTime objects can be compared to any other calendar class that implements
the `utc_rd_values` method.
## Testing Code That Uses DateTime
If you are trying to test code that calls uses DateTime, you may want to be to
explicitly set the value returned by Perl's `time` builtin. This builtin is
called by `DateTime->now` and `DateTime->today`.
You can override `CORE::GLOBAL::time`, but this will only work if you do this
**before** loading DateTime. If doing this is inconvenient, you can also
    caveats below carefully. The results `DateTime` produces are predictable,
    correct, and mostly intuitive, but datetime math gets very ugly when time zones
    are involved, and there are a few strange corner cases involving subtraction of
    two datetimes across a DST change.
    If you can always use the floating or UTC time zones, you can skip ahead to
    ["Leap Seconds and Date Math"](#leap-seconds-and-date-math)
- date vs datetime math
    If you only care about the date (calendar) portion of a datetime, you should
    use either `$dt->delta_md` or `$dt->delta_days`, not `$dt->subtract_datetime`. This will give predictable, unsurprising results,
    free from DST-related complications.
- $dt->subtract\_datetime and $dt->add\_duration
    You must convert your datetime objects to the UTC time zone before doing date
    math if you want to make sure that the following formulas are always true:
        $dt2 - $dt1 = $dur
        $dt1 + $dur = $dt2
    $dt1->add_duration($dur);
    # gives us 2003-04-05 02:58:00 - 1 hour later than $dt1
    $dt2->subtract_duration($dur);
The `$dt->subtract_duration` operation gives us a (perhaps) unexpected
answer because it first subtracts one day to get 2003-04-05T03:01:00 and then
subtracts 3 minutes to get the final result.
If we explicitly reverse the order we can get the original value of `$dt1`.
This can be facilitated by the [DateTime::Duration](https://metacpan.org/pod/DateTime%3A%3ADuration) class's `$dur->calendar_duration` and `$dur->clock_duration` methods:
    $dt2->subtract_duration( $dur->clock_duration )
        ->subtract_duration( $dur->calendar_duration );
### Leap Seconds and Date Math
The presence of leap seconds can cause even more anomalies in date math. For
example, the following is a legal datetime:
    my $dt = DateTime->new(
        year      => 1972,
        month     => 12,
        day       => 31,
zeroes depending on the length of the format specifier. For example, `"h"`
represents the current hour from 1-12. If you specify `"hh"` then hours 1-9
will have a leading zero prepended.
However, CLDR often uses five of a letter to represent the narrow form of a
pattern. This inconsistency is necessary for backwards compatibility.
There are many cases where CLDR patterns distinguish between the "format" and
"stand-alone" forms of a pattern. The format pattern is used when the thing in
question is being placed into a larger string. The stand-alone form is used
when displaying that item by itself, for example in a calendar.
There are also many cases where CLDR provides three sizes for each item, wide
(the full name), abbreviated, and narrow. The narrow form is often just a
single character, for example "T" for "Tuesday", and may not be unique.
CLDR provides a fairly complex system for localizing time zones that we ignore
entirely. The time zone patterns just use the information provided by
`DateTime::TimeZone`, and _do not follow the CLDR spec_.
The output of a CLDR pattern is always localized, when applicable.
    In other, words the "yyyyy" pattern will format year -1234 as "-1234", not
    "-01234".
- yy
    This is a special case. It always produces a two-digit year, so "1976" becomes
    "76". Negative years will start with a "-", making them one character longer.
- Y{1,}
    The year in "week of the year" calendars, from `$dt->week_year`.
- u{1,}
    Same as "y" except that "uu" is not a special case.
- Q{1,2}
    The quarter as a number (1..4).
- QQQ
    print DateTime::Format::HTTP->format_datetime($datetime);
Most format modules are suitable for use as a `formatter` with a DateTime
object.
All format modules start with
[DateTime::Format::](https://metacpan.org/search?q=datetime%3A%3Aformat).
## Calendar Modules
There are a number of modules on CPAN that implement non-Gregorian calendars,
such as the Chinese, Mayan, and Julian calendars.
All calendar modules start with
[DateTime::Calendar::](https://metacpan.org/search?q=datetime%3A%3Acalendar).
## Event Modules
There are a number of modules that calculate the dates for events, such as
Easter, Sunrise, etc.
All event modules start with
[DateTime::Event::](https://metacpan.org/search?q=datetime%3A%3Aevent).
## Others
* sub-second resolution
- more tests: add/subtract/compare
* Other
- document RD days/seconds(/nanosecs?) in a separate document that
will be the reference for DateTime.pm internals, as well as being
useful for other calendar implementors.
- thorough tests for subtraction & addition overloading
NOTE TO FUTURE DEVELOPERS:
Attempting to implement add_duration in XS actually seemed to slow
date math operations down.  Sad but true.
lib/DateTime.pm view on Meta::CPAN
        my %p     = $validator->(@_);
        my $object = delete $p{object};
        if ( $object->isa('DateTime::Infinite') ) {
            return $object->clone;
        }
        my ( $rd_days, $rd_secs, $rd_nanosecs ) = $object->utc_rd_values;
        # A kludge because until all calendars are updated to return all
        # three values, $rd_nanosecs could be undef
        $rd_nanosecs ||= 0;
        # This is a big hack to let _seconds_as_components operate naively
        # on the given value. If the object _is_ on a leap second, we'll
        # add that to the generated seconds value later.
        my $leap_seconds = 0;
        if (   $object->can('time_zone')
            && !$object->time_zone->is_floating
            && $rd_secs > 86399
lib/DateTime.pm view on Meta::CPAN
    $dt->set_time_zone('America/Chicago');
    $dt->set_formatter($formatter);
=head1 DESCRIPTION
DateTime is a class for the representation of date/time combinations, and is
part of the Perl DateTime project.
It represents the Gregorian calendar, extended backwards in time before its
creation (in 1582). This is sometimes known as the "proleptic Gregorian
calendar". In this calendar, the first day of the calendar (the epoch), is the
first day of year 1, which corresponds to the date which was (incorrectly)
believed to be the birth of Jesus Christ.
The calendar represented does have a year 0, and in that way differs from how
dates are often written using "BCE/CE" or "BC/AD".
For infinite datetimes, please see the L<DateTime::Infinite|DateTime::Infinite>
module.
=head1 USAGE
=head2 0-based Versus 1-based Numbers
The C<DateTime> module follows a simple logic for determining whether or not a
lib/DateTime.pm view on Meta::CPAN
This constructor takes the same arguments as can be given to the C<new> method,
except that it does not accept a C<month> or C<day> argument. Instead, it
requires both C<year> and C<day_of_year>. The day of year must be between 1 and
366, and 366 is only allowed for leap years.
=head3 DateTime->from_object( object => $object, ... )
This class method can be used to construct a new DateTime object from any
object that implements the C<utc_rd_values> method. All C<DateTime::Calendar>
modules must implement this method in order to provide cross-calendar
compatibility. This method accepts a C<locale> and C<formatter> parameter
If the object passed to this method has a C<time_zone> method, that is used to
set the time zone of the newly created C<DateTime> object.
Otherwise, the returned object will be in the floating time zone.
=head3 $dt->clone
This object method returns a new object that is replica of the object upon
lib/DateTime.pm view on Meta::CPAN
This method returns the number of days in the current quarter.
=head3 $dt->year_length
This method returns the number of days in the current year.
=head3 $dt->week
   my ( $week_year, $week_number ) = $dt->week;
Returns information about the calendar week for the date. The values returned
by this method are also available separately through the C<< $dt->week_year >>
and C<< $dt->week_number >> methods.
The first week of the year is defined by ISO as the one which contains the
fourth day of January, which is equivalent to saying that it's the first week
to overlap the new year by at least four days.
Typically the week year will be the same as the year that the object is in, but
dates at the very beginning of a calendar year often end up in the last week of
the prior year, and similarly, the final few days of the year may be placed in
the first week of the next year.
=head3 $dt->week_year
Returns the year of the week. See C<< $dt->week >> for details.
=head3 $dt->week_number
Returns the week of the year, from 1..53. See C<< $dt->week >> for details.
lib/DateTime.pm view on Meta::CPAN
C<1325376000> returns C<1325376000>.
=head3 $dt->is_finite, $dt->is_infinite
These methods allow you to distinguish normal datetime objects from infinite
ones. Infinite datetime objects are documented in L<DateTime::Infinite>.
=head3 $dt->utc_rd_values
Returns the current UTC Rata Die days, seconds, and nanoseconds as a three
element list. This exists primarily to allow other calendar modules to create
objects based on the values provided by this object.
=head3 $dt->local_rd_values
Returns the current local Rata Die days, seconds, and nanoseconds as a three
element list. This exists for the benefit of other modules which might want to
use this information for date math, such as L<DateTime::Event::Recurrence>.
=head3 $dt->leap_seconds
lib/DateTime.pm view on Meta::CPAN
UTC times.
Since DateTime objects overload comparison operators, this:
    @dates = sort @dates;
is equivalent to this:
    @dates = sort { DateTime->compare( $a, $b ) } @dates;
DateTime objects can be compared to any other calendar class that implements
the C<utc_rd_values> method.
=head2 Testing Code That Uses DateTime
If you are trying to test code that calls uses DateTime, you may want to be to
explicitly set the value returned by Perl's C<time> builtin. This builtin is
called by C<< DateTime->now >> and C<< DateTime->today >>.
You can override C<CORE::GLOBAL::time>, but this will only work if you do this
B<before> loading DateTime. If doing this is inconvenient, you can also
lib/DateTime.pm view on Meta::CPAN
caveats below carefully. The results C<DateTime> produces are predictable,
correct, and mostly intuitive, but datetime math gets very ugly when time zones
are involved, and there are a few strange corner cases involving subtraction of
two datetimes across a DST change.
If you can always use the floating or UTC time zones, you can skip ahead to
L<Leap Seconds and Date Math>
=item * date vs datetime math
If you only care about the date (calendar) portion of a datetime, you should
use either C<< $dt->delta_md >> or C<< $dt->delta_days >>, not C<<
$dt->subtract_datetime >>. This will give predictable, unsurprising results,
free from DST-related complications.
=item * $dt->subtract_datetime and $dt->add_duration
You must convert your datetime objects to the UTC time zone before doing date
math if you want to make sure that the following formulas are always true:
    $dt2 - $dt1 = $dur
lib/DateTime.pm view on Meta::CPAN
    # gives us 2003-04-05 02:58:00 - 1 hour later than $dt1
    $dt2->subtract_duration($dur);
The C<< $dt->subtract_duration >> operation gives us a (perhaps) unexpected
answer because it first subtracts one day to get 2003-04-05T03:01:00 and then
subtracts 3 minutes to get the final result.
If we explicitly reverse the order we can get the original value of C<$dt1>.
This can be facilitated by the L<DateTime::Duration> class's C<<
$dur->calendar_duration >> and C<< $dur->clock_duration >> methods:
    $dt2->subtract_duration( $dur->clock_duration )
        ->subtract_duration( $dur->calendar_duration );
=head3 Leap Seconds and Date Math
The presence of leap seconds can cause even more anomalies in date math. For
example, the following is a legal datetime:
    my $dt = DateTime->new(
        year      => 1972,
        month     => 12,
        day       => 31,
lib/DateTime.pm view on Meta::CPAN
zeroes depending on the length of the format specifier. For example, C<"h">
represents the current hour from 1-12. If you specify C<"hh"> then hours 1-9
will have a leading zero prepended.
However, CLDR often uses five of a letter to represent the narrow form of a
pattern. This inconsistency is necessary for backwards compatibility.
There are many cases where CLDR patterns distinguish between the "format" and
"stand-alone" forms of a pattern. The format pattern is used when the thing in
question is being placed into a larger string. The stand-alone form is used
when displaying that item by itself, for example in a calendar.
There are also many cases where CLDR provides three sizes for each item, wide
(the full name), abbreviated, and narrow. The narrow form is often just a
single character, for example "T" for "Tuesday", and may not be unique.
CLDR provides a fairly complex system for localizing time zones that we ignore
entirely. The time zone patterns just use the information provided by
C<DateTime::TimeZone>, and I<do not follow the CLDR spec>.
The output of a CLDR pattern is always localized, when applicable.
lib/DateTime.pm view on Meta::CPAN
In other, words the "yyyyy" pattern will format year -1234 as "-1234", not
"-01234".
=item * yy
This is a special case. It always produces a two-digit year, so "1976" becomes
"76". Negative years will start with a "-", making them one character longer.
=item * Y{1,}
The year in "week of the year" calendars, from C<< $dt->week_year >>.
=item * u{1,}
Same as "y" except that "uu" is not a special case.
=item * Q{1,2}
The quarter as a number (1..4).
=item * QQQ
lib/DateTime.pm view on Meta::CPAN
    print DateTime::Format::HTTP->format_datetime($datetime);
Most format modules are suitable for use as a C<formatter> with a DateTime
object.
All format modules start with
L<DateTime::Format::|https://metacpan.org/search?q=datetime%3A%3Aformat>.
=head2 Calendar Modules
There are a number of modules on CPAN that implement non-Gregorian calendars,
such as the Chinese, Mayan, and Julian calendars.
All calendar modules start with
L<DateTime::Calendar::|https://metacpan.org/search?q=datetime%3A%3Acalendar>.
=head2 Event Modules
There are a number of modules that calculate the dates for events, such as
Easter, Sunrise, etc.
All event modules start with
L<DateTime::Event::|https://metacpan.org/search?q=datetime%3A%3Aevent>.
=head2 Others
lib/DateTime/Duration.pm view on Meta::CPAN
    wantarray ? @ret{@units} : $ret{ $units[0] };
}
sub is_wrap_mode     { $_[0]->{end_of_month} eq 'wrap'     ? 1 : 0 }
sub is_limit_mode    { $_[0]->{end_of_month} eq 'limit'    ? 1 : 0 }
sub is_preserve_mode { $_[0]->{end_of_month} eq 'preserve' ? 1 : 0 }
sub end_of_month_mode { $_[0]->{end_of_month} }
sub calendar_duration {
    my $self = shift;
    return ( ref $self )
        ->new( map { $_ => $self->{$_} } qw( months days end_of_month ) );
}
sub clock_duration {
    my $self = shift;
    return ( ref $self )
lib/DateTime/Duration.pm view on Meta::CPAN
false for B<all> of these methods.
=head2 $dur->is_wrap_mode, $dur->is_limit_mode, $dur->is_preserve_mode
Indicates what mode is used for end of month wrapping.
=head2 $dur->end_of_month_mode
Returns one of C<"wrap">, C<"limit">, or C<"preserve">.
=head2 $dur->calendar_duration
Returns a new object with the same I<calendar> delta (months and days only) and
end of month mode as the current object.
=head2 $dur->clock_duration
Returns a new object with the same I<clock> deltas (minutes, seconds, and
nanoseconds) and end of month mode as the current object.
=head2 $dur->inverse( ... )
Returns a new object with the same deltas as the current object, but multiplied
## no critic (Subroutines::ProtectPrivateSubs)
# test _ymd2rd and _rd2ymd for various dates
# 2 tests are performed for each date (on _ymd2rd and _rd2ymd)
# dates are specified as [rd,year,month,day]
for (    # min and max supported days (for 32-bit system)
    [ -( 2**28 ), -734951, 9, 7 ],
    [ 2**28,       734952, 4, 25 ],
    # some miscellaneous dates (these are actually epoch dates for
    # various calendars from Calendrical Calculations (1st ed) Table
    # 1.1)
    [ -1721425, -4713, 11, 24 ],
    [ -1373427, -3760, 9,  7 ],
    [ -1137142, -3113, 8,  11 ],
    [ -1132959, -3101, 1,  23 ],
    [ -963099,  -2636, 2,  15 ],
    [ -1,        0,    12, 30 ], [ 1, 1, 1, 1 ],
    [  2796,     8,    8,  27 ],
    [  103605,   284,  8,  29 ],
    [  226896,   622,  3,  22 ],
t/11duration.t view on Meta::CPAN
        weeks       => 3,
        days        => 4,
        hours       => 6,
        minutes     => 7,
        seconds     => 8,
        nanoseconds => 9,
    );
    my $dur = DateTime::Duration->new( %pairs, end_of_month => 'limit' );
    my $calendar_dur = $dur->calendar_duration;
    is( $calendar_dur->delta_months,  14, 'date - delta_months is 14' );
    is( $calendar_dur->delta_minutes, 0,  'date - delta_minutes is 0' );
    is( $calendar_dur->delta_seconds, 0,  'date - delta_seconds is 0' );
    is(
        $calendar_dur->delta_nanoseconds, 0,
        'date - delta_nanoseconds is 0'
    );
    ok( $calendar_dur->is_limit_mode, 'limit mode' );
    my $clock_dur = $dur->clock_duration;
    is( $clock_dur->delta_months,      0,   'time  - delta_months is 0' );
    is( $clock_dur->delta_minutes,     367, 'time  - delta_minutes is 367' );
    is( $clock_dur->delta_seconds,     8,   'time  - delta_seconds is 8' );
    is( $clock_dur->delta_nanoseconds, 9, 'time  - delta_nanoseconds is 9' );
    ok( $clock_dur->is_limit_mode, 'limit mode' );
}
{
t/24from-object.t view on Meta::CPAN
is( $dt1->year,       1970, 'year is 1970' );
is( $dt1->hour,       1,    'hour is 1' );
is( $dt1->nanosecond, 100,  'nanosecond is 100' );
{
    my $t1 = DateTime::Calendar::_Test::WithoutTZ->new(
        rd_days => 1,
        rd_secs => 0
    );
    # Tests creating objects from other calendars (without time zones)
    my $t2 = DateTime->from_object( object => $t1 );
    isa_ok( $t2, 'DateTime' );
    is(
        $t2->datetime, '0001-01-01T00:00:00',
        'convert from object without tz'
    );
    ok( $t2->time_zone->is_floating, 'time_zone is floating' );
}
{
    my $tz = DateTime::TimeZone->new( name => 'America/Chicago' );
    my $t1 = DateTime::Calendar::_Test::WithTZ->new(
        rd_days   => 1, rd_secs => 0,
        time_zone => $tz
    );
    # Tests creating objects from other calendars (with time zones)
    my $t2 = DateTime->from_object( object => $t1 );
    isa_ok( $t2, 'DateTime' );
    is( $t2->time_zone->name, 'America/Chicago', 'time_zone is preserved' );
}
{
    my $tz = DateTime::TimeZone->new( name => 'UTC' );
    my $t1 = DateTime::Calendar::_Test::WithTZ->new(
        rd_days => 720258,
t/38local-subtract.t view on Meta::CPAN
        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'
    );
xt/author/pp-09greg.t view on Meta::CPAN
## no critic (Subroutines::ProtectPrivateSubs)
# test _ymd2rd and _rd2ymd for various dates
# 2 tests are performed for each date (on _ymd2rd and _rd2ymd)
# dates are specified as [rd,year,month,day]
for (    # min and max supported days (for 32-bit system)
    [ -( 2**28 ), -734951, 9, 7 ],
    [ 2**28,       734952, 4, 25 ],
    # some miscellaneous dates (these are actually epoch dates for
    # various calendars from Calendrical Calculations (1st ed) Table
    # 1.1)
    [ -1721425, -4713, 11, 24 ],
    [ -1373427, -3760, 9,  7 ],
    [ -1137142, -3113, 8,  11 ],
    [ -1132959, -3101, 1,  23 ],
    [ -963099,  -2636, 2,  15 ],
    [ -1,        0,    12, 30 ], [ 1, 1, 1, 1 ],
    [  2796,     8,    8,  27 ],
    [  103605,   284,  8,  29 ],
    [  226896,   622,  3,  22 ],
xt/author/pp-11duration.t view on Meta::CPAN
        weeks       => 3,
        days        => 4,
        hours       => 6,
        minutes     => 7,
        seconds     => 8,
        nanoseconds => 9,
    );
    my $dur = DateTime::Duration->new( %pairs, end_of_month => 'limit' );
    my $calendar_dur = $dur->calendar_duration;
    is( $calendar_dur->delta_months,  14, 'date - delta_months is 14' );
    is( $calendar_dur->delta_minutes, 0,  'date - delta_minutes is 0' );
    is( $calendar_dur->delta_seconds, 0,  'date - delta_seconds is 0' );
    is(
        $calendar_dur->delta_nanoseconds, 0,
        'date - delta_nanoseconds is 0'
    );
    ok( $calendar_dur->is_limit_mode, 'limit mode' );
    my $clock_dur = $dur->clock_duration;
    is( $clock_dur->delta_months,      0,   'time  - delta_months is 0' );
    is( $clock_dur->delta_minutes,     367, 'time  - delta_minutes is 367' );
    is( $clock_dur->delta_seconds,     8,   'time  - delta_seconds is 8' );
    is( $clock_dur->delta_nanoseconds, 9, 'time  - delta_nanoseconds is 9' );
    ok( $clock_dur->is_limit_mode, 'limit mode' );
}
{
xt/author/pp-24from-object.t view on Meta::CPAN
is( $dt1->year,       1970, 'year is 1970' );
is( $dt1->hour,       1,    'hour is 1' );
is( $dt1->nanosecond, 100,  'nanosecond is 100' );
{
    my $t1 = DateTime::Calendar::_Test::WithoutTZ->new(
        rd_days => 1,
        rd_secs => 0
    );
    # Tests creating objects from other calendars (without time zones)
    my $t2 = DateTime->from_object( object => $t1 );
    isa_ok( $t2, 'DateTime' );
    is(
        $t2->datetime, '0001-01-01T00:00:00',
        'convert from object without tz'
    );
    ok( $t2->time_zone->is_floating, 'time_zone is floating' );
}
{
    my $tz = DateTime::TimeZone->new( name => 'America/Chicago' );
    my $t1 = DateTime::Calendar::_Test::WithTZ->new(
        rd_days   => 1, rd_secs => 0,
        time_zone => $tz
    );
    # Tests creating objects from other calendars (with time zones)
    my $t2 = DateTime->from_object( object => $t1 );
    isa_ok( $t2, 'DateTime' );
    is( $t2->time_zone->name, 'America/Chicago', 'time_zone is preserved' );
}
{
    my $tz = DateTime::TimeZone->new( name => 'UTC' );
    my $t1 = DateTime::Calendar::_Test::WithTZ->new(
        rd_days => 720258,
xt/author/pp-38local-subtract.t view on Meta::CPAN
        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'
    );