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

SparkeyG has asked for the wisdom of the Perl Monks concerning the following question:

I think I found a bug in DateTime's strftime. If you have a nanosecond value that rounds up to a full second, it returns instead a tenth of a second. Pls see the example code and output for details. Am I seeing this correctly? If so I will submit a bug to the maintainers. Sample Code:
use strict; use warnings; use DateTime; use DateTime::Format::Strptime; my $val = "2011-11-11 14:30:00.999981"; my $format = new DateTime::Format::Strptime( pattern => '%F %T.%N', time_zone => 'GMT', ); my $date = $format->parse_datetime($val); print $date->strftime("%F %T.%3N %Z")."\n";
Output:
2011-11-11 14:30:00.1000 UTC
I would expect:
2011-11-11 14:30:01.000 UTC

Replies are listed 'Best First'.
Re: Rounding Issue in DateTime strftime?
by runrig (Abbot) on Nov 14, 2011 at 18:23 UTC

    Update: Looks like bug is reported as rt://72416

    Yes, looks like it's a bug due to rounding and not carrying over to the next unit. It looks harder to carry over rounded nanoseconds to seconds than to just truncate, so here's my not quite ideal but better than what it's doing now replacements for some methonds in DateTime.pm:

    sub _format_nanosecs { my $self = shift; my $precision = @_ ? shift : 9; my $divide_by = 10**( 9 - $precision ); my $t = sprintf( '%0' . $precision . 'u', round( $self->{rd_nanosecs} / $divide_by ) ); return ( length($t) > $precision ) ? "9" x $precision : $t; }

    Update: IMHO, this solution is better than my other fix which correctly rounds the fractions of a second and carries over to the seconds place. E.g., what if you are only printing out seconds and fractions (with strftime template "%S.%3N")? Would you rather see "59.999" or "00.000"? I think it's better to not let nanoseconds affect the rest of the units.

      Yeah, I decided to go ahead and report the bug. As to the suggestion of truncating, wouldn't that revert rt://66744
        No, this only truncates if the nanoseconds round up to 1 second (assuming it works correctly).
        I submitted a patch to rt://72416 to correctly round, but I'm not sure that rounding is better than truncating. Though either is better than what it is doing now :-)