http://qs321.pair.com?node_id=11110679


in reply to [ DateTime::Duration ] off by one problem with negative seconds

If I were to supply a value for nano- or microsecond, I would have thought that an integer would have been sufficient, and not to have supply a string for the value.

few minutes later ... From the pod with original emphasis (untested if this would solve the issue):

DateTime::Duration->new( ... )

This method takes the parameters "years", "months", "weeks", "days", "hours", "minutes", "seconds", "nanoseconds", and "end_of_month". All of these except "end_of_month" are numbers. If any of the numbers are negative, the entire duration is negative.

All of the numbers must be integers.

  • Comment on Re: [ DateTime::Duration ] off by one problem with negative seconds

Replies are listed 'Best First'.
Re^2: [ DateTime::Duration ] off by one problem with negative seconds
by LanX (Saint) on Dec 28, 2019 at 02:18 UTC
    Many thanks a +0 to explicitly convert to number is fixing the issue.

    > If I were to supply a value for nano- or microsecond, I would have thought that an integer would have been sufficient, and not to have supply a string for the value.

    The string is an artefact from an sprintf to convert non-nanos to nanos.

    > All of the numbers must be integers.

    It's Perl's dogma to treat all convertible scalars alike, including integers and strings of integers.

    DB<75> use warnings; print "001"+"001" # no warnings 2 DB<76>

    I read the docs as "don't pass real numbers".

    Keep in mind that the nanosecs could have been read from a file and come as string inside a variable.

    DT::D only fails in this special case and I suppose it's because there is an inner test for falseness to see if the nanosecs are 0 ... but "000000000" OTOH is true.

    some minutes later

    My Boolean theory seems to be right, passing "0" works fine (false), but "00" fails (true).

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      > I suppose it's because there is an inner test for falseness to see if the nanosecs are 0 ... but "000000000" OTOH is true.

      found the problem in the constructor

      if ( $p{nanoseconds} ) { # <-- +0 sho +uld fix it $self->{nanoseconds} = $p{nanoseconds}; $self->_normalize_nanoseconds; } else { # shortcut - if they don't need nanoseconds $self->{nanoseconds} = 0; } ... # and later # make the signs of seconds, nanos the same; 0 < abs(nanos) < MAX_NANO +S # NB this requires nanoseconds != 0 (callers check this already) # <- +- GOTCHA! sub _normalize_nanoseconds { ...

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice