Provided by: libdatetime-format-duration-perl_1.04-1_all bug

NAME

       DateTime::Format::Duration - Format and parse DateTime::Durations

VERSION

       version 1.04

SYNOPSIS

           use DateTime::Format::Duration;

           $d = DateTime::Format::Duration->new(
               pattern => '%Y years, %m months, %e days, '.
                       '%H hours, %M minutes, %S seconds'
           );

           print $d->format_duration(
               DateTime::Duration->new(
                   years   => 3,
                   months  => 5,
                   days    => 1,
                   hours   => 6,
                   minutes => 15,
                   seconds => 45,
                   nanoseconds => 12000
               )
           );
           # 3 years, 5 months, 1 days, 6 hours, 15 minutes, 45 seconds

           $duration = $d->parse_duration(
               '3 years, 5 months, 1 days, 6 hours, 15 minutes, 45 seconds'
           );
           # Returns DateTime::Duration object

           print $d->format_duration_from_deltas(
               years   => 3,
               months  => 5,
               days    => 1,
               hours   => 6,
               minutes => 15,
               seconds => 45,
               nanoseconds => 12000
           );
           # 3 years, 5 months, 1 days, 6 hours, 15 minutes, 45 seconds

           %deltas = $d->parse_duration_as_deltas(
                 '3 years, 5 months, 1 days, 6 hours, 15 minutes, 45 seconds'
           );
           # Returns hash:
           # (years=>3, months=>5, days=>1, hours=>6, minutes=>15, seconds=>45)

ABSTRACT

       This module formats and parses DateTime::Duration objects as well as other durations representations.

CONSTRUCTOR

       This module contains a single constructor:

       •   new( ... )

           The "new" constructor takes the following attributes:

           •   "pattern => $string"

               This  is  a  strf type pattern detailing the format of the duration.  See the "Patterns" sections
               below for more information.

           •   "normalise => $one_or_zero_or_ISO"

           •   "normalize => $one_or_zero_or_ISO"

               This determines whether durations are 'normalised'.  For  example,  does  120  seconds  become  2
               minutes?

               Setting  this value to true without also setting a "base" means we will normalise without a base.
               See the "Normalising without a base" section below.

           •   "base => $datetime_object"

               If a base DateTime is given then that is the normalisation date. Setting this attribute overrides
               the above option and sets normalise to true.

METHODS

       DateTime::Format::Duration has the following methods:

       •   format_duration( $datetime_duration_object )

       •   "format_duration( duration => $dt_duration, pattern => $pattern )"

           Returns a string representing a DateTime::Duration object in the format set by the  pattern.  If  the
           first  form  is  used,  the  pattern is taken from the object. If the object has no pattern then this
           method will croak.

       •   format_duration_from_deltas( %deltas )

       •   "format_duration_from_deltas( %deltas, pattern => $pattern )"

           As above, this method returns a string representing a duration in the  format  set  by  the  pattern.
           However  this  method  takes a hash of values. Permissible hash keys are "years, months, days, hours,
           minutes, seconds" and "nanoseconds" as well as "negative" which,  if  true,  inverses  the  duration.
           ("years => -1" is the same as "years => 1, negative=>1")

       •   parse_duration( $string )

           This  method  takes a string and returns a DateTime::Duration object that is the equivalent according
           to the pattern.

       •   parse_duration_as_deltas( $string )

           Once again, this method is the same as above, however it returns a hash rather than an object.

       •   normalise( $duration_object )

       •   normalize( %deltas )

           Returns a hash of deltas after normalising the input. See the  "NORMALISE"  section  below  for  more
           information.

ACCESSORS

       •   pattern()

           Returns the current pattern.

       •   base()

           Returns the current base.

       •   normalising()

           Indicates whether or not the durations are being normalised.

SETTERS

       All setters return the object so that they can be strung together.

       •   set_pattern( $new_pattern )

           Sets the pattern and returns the object.

       •   set_base( $new_DateTime )

           Sets the base DateTime and returns the object.

       •   set_normalising( $true_or_false_or_ISO )

           Turns normalising on or off and returns the object.

NOTES

   Patterns
       This  module  uses  a  similar  set  of  patterns  to strftime. These patterns have been kept as close as
       possible to the original time-based patterns.

       •   %C

           The number of hundreds of years in the duration. 400 years  would  return  4.   This  is  similar  to
           centuries.

       •   %d

           The  number  of  days  zero-padded  to two digits. 2 days returns 02. 22 days returns 22 and 220 days
           returns 220.

       •   %e

           The number of days.

       •   %F

           Equivalent of %Y-%m-%d

       •   %H

           The number of hours zero-padded to two digits.

       •   %I

           Same as %H

       •   %j

           The duration expressed in whole days. 36 hours returns 1

       •   %k

           The hours without any padding

       •   %l

           Same as %k

       •   %m

           The months, zero-padded to two digits

       •   %M

           The minutes, zero-padded to two digits

       •   %n

           A linebreak when formatting and any whitespace when parsing

       •   %N

           Nanoseconds - see note on precision at end

       •   %p

           Either a '+' or a '-' indicating the positiveness of the duration

       •   %P

           A '-' for negative durations and nothing for positive durations.

       •   %r

           Equivalent of %H:%M:%S

       •   %R

           Equivalent of %H:%M

       •   %s

           Returns the value as seconds. 1 day, 5 seconds return 86405

       •   %S

           Returns the seconds, zero-padded to two digits

       •   %t

           A tab character when formatting or any whitespace when parsing

       •   %T

           Equivalent of %P%H:%M:%S

       •   %u

           Days after weeks are removed. 4 days returns 4, but 22 days returns 1 (22 days is three weeks, 1 day)

       •   %V

           Duration expressed as weeks. 355 days returns 52.

       •   %W

           Duration expressed as floating weeks. 10 days, 12 hours returns 1.5 weeks.

       •   %y

           Years in the century. 145 years returns 45.

       •   %Y

           Years, zero-padded to four digits

       •   %%

           A '%' symbol

       Precision can be changed for any and all the above values. For all but nanoseconds (%N), the precision is
       the zero-padding. To change the precision insert a number between the '%' and the letter. For example:  1
       year formatted with %6Y would return 000001 rather than the default 0001. Likewise, to remove padding %1Y
       would just return a 1.

       Nanosecond  precision  is  the  other  way  (nanoseconds are fractional and thus should be right padded).
       123456789  nanoseconds  formatted  with  %3N  would  return  123  and  formatted  as  %12N  would  return
       123456789000.

   Normalisation
       This  module  contains a complex method for normalising durations. The method ensures that the values for
       all components are as close to zero as possible.  Rather than returning 68 minutes, it is normalised to 1
       hour, 8 minutes.

       The complexity comes from three places:

       •   Mixed positive and negative components

           The duration of 1 day, minus 2 hours is easy to normalise in your head to 22 hours. However  consider
           something more complex such as -2 years, +1 month, +22 days, +11 hours, -9 minutes.

           This  module works from lowest to highest precision to calculate the duration.  So, based on a "base"
           of 2004-03-28T00:00:00 the following transformations take place:

               2003-01-01T00:00:00 - 2 years   = 2001-01-01T00:00:00 === -2 years
               2001-01-01T00:00:00 + 1 month   = 2001-02-01T00:00:00 === -1 year, 11 months
               2001-02-01T00:00:00 + 22 days   = 2001-02-23T00:00:00 === -1yr, 10mths, 6days
               2001-02-22T00:00:00 + 11 hours  = 2001-02-23T11:00:00 === -1y, 10m, 6d, 13h
               2001-02-22T11:00:00 - 9 minutes = 2001-02-23T10:51:00 === -1y, 10m, 6d, 13h, 9m
           See:                                https://raw.githubusercontent.com/karenetheridge/DateTime-Format-
           Duration/master/docs/figure1.gif

           Figure  1  illustrates that, with the given base, -2 years, +1 month, +22 days, +11 hours, -9 minutes
           is normalised to -1 year, 10 months, 6 days, 13 hours and 9 minutes.

       •   Months of unequal length.

           Unfortunately months can have 28, 29, 30 or 31 days and it can change from year to year.  Thus  if  I
           wanted  to  normalise 2 months it could be any of 59 (Feb-Mar), 60 (Feb-Mar in a leap year), 61 (Mar-
           Apr, Apr-May, May-Jun, Jun-Jul, Aug-Sep, Sep-Oct, Oct-Nov or Nov-Dec) or 62  days  (Dec-Jan  or  Jul-
           Aug).  Because  of  this  the  module  uses  a base datetime for its calculations. If we use the base
           2003-01-01T00:00:00 then two months would be 59 days (2003-03-01 - 2003-01-01)

       •   The order of components

           Components will always be assessed from lowest to highest  precision  (years,  months,  days,  hours,
           minutes, seconds, nanoseconds). This can really change things.

           Consider  the duration of 1 day, 24 hours. Normally this will normalise to 2 days.  However, consider
           changes to Daylight Savings. On the changes to and from DST days have 25 and 23 hours.

           If we take the base DateTime as midnight on the day DST ends (when there's 25 hours in the day),  and
           add 1 day, 24 hours we end up at midnight 2 days later.  So our duration normalises to two days.

           However,  if we add 24 hours, 1 day we end up at 11pm on the next day! Why is this?  Because midnight
           + 24 hours = 11pm (there's 25 hours on this day!), then we add 1 day  and  end  up  at  11pm  on  the
           following      day.       See:      https://raw.githubusercontent.com/karenetheridge/DateTime-Format-
           Duration/master/docs/figure2.gif

           Figure 2 illustrates the above problem on timelines.

       •   Leap years and leap seconds

           Leap years and seconds further add to the confusion in normalisation. Leap  seconds  mean  there  are
           minutes  that  are  61  seconds  long,  thus  130 seconds can be 2 minutes, 10 seconds or 2 minutes 9
           seconds, depending on the base DateTime.  Similarly leap years mean a day  can  have  23,  24  or  25
           hours.              See:            https://raw.githubusercontent.com/karenetheridge/DateTime-Format-
           Duration/master/docs/figure3.gif

           Figure 3 shows how leaps are calculated on timelines.

   Normalising without a base
       This module includes two ways to normalise without a base.

       •   Standard Normalisation

           Using standard normalisation without a base, 45 days will stay as 45 days  as  there  is  no  way  to
           accurately convert to months. However the following assumptions will be made: There are 24 hours in a
           day and there are 60 seconds in a minute.

       •   ISO Normalisation

           In  ISO8601v2000,  Section 5.5.3.2 says that "The values used must not exceed the 'carry-over points'
           of 12 months, 30 days, 24 hours, 60 minutes and 60 seconds".  Thus if you set the normalise option of
           the constructor, or use set_normalising to 'ISO', months will be normalised to 30 days.

   Deltas vs Duration Objects
       This module can bypass duration objects and just work with delta hashes.  This used  to  be  of  greatest
       value  with  earlier  versions  of DateTime::Duration when DateTime::Duration assumed a duration with one
       negative component was a negative duration (that is, -2 hours, 34 minutes was assumed to be -2 hours, -34
       minutes).

       These extra methods have been left in here firstly for  backwards-compatibility  but  also  as  an  added
       'syntactic sugar'. Consider these two equivalent expressions:

           $one = $o->format_duration(
               DateTime::Duration->new(
                   years => -2,
                   days  => 13,
                   hours => -1
               )
           );

           $two = $o->format_duration_from_deltas(
               years => -2,
               days  => 13,
               hours => -1
           );

       These  both  create  the same string in $one and $two, but if you don't already have a DateTime::Duration
       object, the later looks cleaner.

SEE ALSO

       datetime@perl.org mailing list

       http://datetime.perl.org/

SUPPORT

       Bugs        may        be        submitted        through        the        RT        bug         tracker
       <https://rt.cpan.org/Public/Dist/Display.html?Name=DateTime-Format-Duration>                          (or
       bug-DateTime-Format-Duration@rt.cpan.org <mailto:bug-DateTime-Format-Duration@rt.cpan.org>).

       There   is   also   a   mailing    list    available    for    users    of    this    distribution,    at
       <http://lists.perl.org/list/datetime.html>.

       I am also usually active on irc, as 'ether' at "irc.perl.org".

AUTHOR

       Rick Measham <rickm@cpan.org>

CONTRIBUTOR

       Karen Etheridge <ether@cpan.org>

COPYRIGHT AND LICENCE

       This software is copyright (c) 2003 by Rick Measham.

       This  is  free  software;  you  can  redistribute  it and/or modify it under the same terms as the Perl 5
       programming language system itself.

perl v5.40.1                                       2025-09-22                    DateTime::Format::Duration(3pm)