Subject: | Odd malfunction of normalize() |
The normalize subroutine is inexplicably breaking with a very particular
pair of dates. My relevant code looks like:
sub timeconv {
my($expiry, $block_time) = @_;
my $duration = $expiry - $block_time;
use Data::Dumper;
print Dumper \$block_time, \$expiry, \$duration;
my $formatter = DateTime::Format::Duration->new(
pattern => '%Y years, %m months, %e days, %H hours, %M minutes, %S
seconds',
normalize => 1,
base => $block_time,
);
my %normalized = $formatter->normalize($duration);
print Dumper \%normalized;
my @periods = ('years','months','days','hours','minutes','seconds');
my $output;
if ($normalized{'minutes'} || $normalized{'seconds'}) {
$output = sprintf('until %s %s ', $expiry->ymd, $expiry->hms);
} else {
foreach (@periods) {
$output .= sprintf('%s %s, ', $normalized{$_}, $_) if $normalized{$_};
if ($normalized{$_} == 1) {
my $singular = $_;
$singular =~ s/s$//;
$output =~ s/$_/$singular/;
}
}
$output =~ s/, $/ /;
}
return $output;
}
$expiry and $block_time are DateTime objects, in UTC. For most cases,
this is working fine. In one particular case, though, it breaks down.
The output of the first Data::Dumper call in this situation looks like:
$VAR1 = \bless( {
'local_rd_secs' => 5297,
'local_rd_days' => 732729,
'rd_nanosecs' => 0,
'locale' => bless( {
'default_time_format_length' =>
'medium',
'native_territory' => 'United
States',
'native_language' => 'English',
'real_class' => 'en',
'native_complete_name' =>
'English United States',
'en_language' => 'English',
'default_date_format_length' =>
'medium',
'id' => 'en_US',
'en_territory' => 'United States',
'en_complete_name' => 'English
United States'
}, 'DateTime::Locale::en' ),
'local_c' => {
'hour' => 1,
'second' => 17,
'month' => 2,
'quarter' => 1,
'day_of_year' => 53,
'day_of_quarter' => 53,
'minute' => 28,
'day' => 22,
'day_of_week' => 4,
'year' => 2007
},
'utc_rd_secs' => 5297,
'formatter' => undef,
'tz' => bless( {
'name' => 'UTC'
}, 'DateTime::TimeZone::UTC' ),
'utc_year' => 2008,
'utc_rd_days' => 732729,
'offset_modifier' => 0
}, 'DateTime' );
$VAR2 = \bless( {
'local_rd_secs' => 5297,
'local_rd_days' => 732771,
'rd_nanosecs' => 0,
'locale' => ${$VAR1}->{'locale'},
'local_c' => {
'hour' => 1,
'second' => 17,
'month' => 4,
'quarter' => 2,
'day_of_year' => 95,
'day_of_quarter' => 5,
'minute' => 28,
'day' => 5,
'day_of_week' => 4,
'year' => 2007
},
'utc_rd_secs' => 5297,
'formatter' => undef,
'tz' => bless( {
'name' => 'UTC'
}, 'DateTime::TimeZone::UTC' ),
'utc_year' => 2008,
'utc_rd_days' => 732771,
'offset_modifier' => 0
}, 'DateTime' );
$VAR3 = \bless( {
'seconds' => 0,
'minutes' => 0,
'end_of_month' => 'wrap',
'nanoseconds' => 0,
'days' => 11,
'months' => 1
}, 'DateTime::Duration' );
While the second outputs:
$VAR1 = {
'seconds' => 0,
'hours' => 0,
'years' => 0,
'minutes' => 0,
'months' => 1,
'days' => 8,
'nanoseconds' => 0
};
And the subroutine itself, using %normalized, outputs "1 month 8 days".
Something is obviously going wrong, causing DateTime::Format::Duration
to normalize 1 month 11 days to 1 month 8 days, though I can't figure
out what. Ideas?