Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the DateTime CPAN distribution.

Report information
The Basics
Id: 41375
Status: resolved
Priority: 0/
Queue: DateTime

People
Owner: Nobody in particular
Requestors: andy.switala [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Simple scalars are insufficient for DateTime math
Date: Tue, 02 Dec 2008 09:09:08 -0500
To: bug-DateTime [...] rt.cpan.org
From: Andrew Switala <andy.switala [...] gmail.com>
Hi, The following applies to DateTime 0.45 on Perl 5.10.0 (Win32). This is wrong: $ perl -mDateTime -e "print ((DateTime->new(year => 1970, \ time_zone => 'UTC')->subtract_datetime_absolute(DateTime->new(year \ => 1583, time_zone => 'UTC')))->seconds)" 12212553600 Conversely: $ perl -mDateTime -e "print DateTime->new(year => 1583, \ time_zone => 'UTC')->add(seconds=>12212553600)" 1582-12-31T23:59:59 $ perl -mDateTime -mMath::BigInt -e "print DateTime->new(year \ => 1583,time_zone=>'UTC')->add(seconds => \ Math::BigInt->new('12212553600'))" The 'seconds' parameter ("12212553600") to DateTime::Duration::new was a 'hashref object', which is not one of the allowed types: scalar at C:/strawberry/perl/site/lib/DateTime/Duration.pm line 26 DateTime::Duration::new(undef, 'seconds', 'Math::BigInt=HASH(0x1babaa4)' ) called at C:/strawberry/perl/site/lib/DateTime.pm line 1519 DateTime::add('DateTime=HASH(0x3a224)', 'seconds', 'Math::BigInt=HASH(0x1babaa4)') called at -e line 1 As a work-around, my code has to deal with three separate cases: 1. Prior to 1972 - before leap seconds were introduced, so convert delta seconds > 2**32 to delta weeks and days < 2**32 (so far). 2. 1972 to 6 months from now - delta seconds fits in a 32 bit integer 3. More than 6 months from now - leap seconds are unknown, so delta seconds are uncertain, might as well convert to delta weeks and days. ^^^ Not having to deal with this sort of thing is the reason one uses a date library in the first place. DateTime is otherwise an excellent module. -- Andy Switala
Subject: Re: [rt.cpan.org #41375] Simple scalars are insufficient for DateTime math
Date: Tue, 2 Dec 2008 23:42:22 +0100
To: bug-DateTime [...] rt.cpan.org
From: "Flavio S. Glock" <fglock [...] gmail.com>
2008/12/2 Andrew Switala via RT <bug-DateTime@rt.cpan.org>: Show quoted text
> Tue Dec 02 09:09:39 2008: Request 41375 was acted upon. > Transaction: Ticket created by andy.switala@gmail.com > Queue: DateTime > Subject: Simple scalars are insufficient for DateTime math > Broken in: (no value) > Severity: (no value) > Owner: Nobody > Requestors: andy.switala@gmail.com > Status: new > Ticket <URL: http://rt.cpan.org/Ticket/Display.html?id=41375 > > > > Hi, > > The following applies to DateTime 0.45 on Perl 5.10.0 (Win32). > > This is wrong: > > $ perl -mDateTime -e "print ((DateTime->new(year => 1970, \ > time_zone => 'UTC')->subtract_datetime_absolute(DateTime->new(year \ > => 1583, time_zone => 'UTC')))->seconds)" > 12212553600 > > Conversely: > > $ perl -mDateTime -e "print DateTime->new(year => 1583, \ > time_zone => 'UTC')->add(seconds=>12212553600)" > 1582-12-31T23:59:59 > > $ perl -mDateTime -mMath::BigInt -e "print DateTime->new(year \ > => 1583,time_zone=>'UTC')->add(seconds => \ > Math::BigInt->new('12212553600'))" > The 'seconds' parameter ("12212553600") to DateTime::Duration::new was a > 'hashref object', which is not one of the allowed types: scalar at > C:/strawberry/perl/site/lib/DateTime/Duration.pm line 26 > DateTime::Duration::new(undef, 'seconds', > 'Math::BigInt=HASH(0x1babaa4)' > ) called at C:/strawberry/perl/site/lib/DateTime.pm line 1519 > DateTime::add('DateTime=HASH(0x3a224)', 'seconds', > 'Math::BigInt=HASH(0x1babaa4)') called at -e line 1 > > As a work-around, my code has to deal with three separate cases: > 1. Prior to 1972 - before leap seconds were introduced, so convert delta > seconds > 2**32 to delta weeks and days < 2**32 (so far). > 2. 1972 to 6 months from now - delta seconds fits in a 32 bit integer > 3. More than 6 months from now - leap seconds are unknown, so delta > seconds are uncertain, might as well convert to delta weeks and days. > > ^^^ Not having to deal with this sort of thing is the reason one uses a > date library in the first place. DateTime is otherwise an excellent module. > > -- > Andy Switala > >
Maybe you need a module DateTime::BigInt ? There is no such module yet. There has been some discussion in the DateTime list during the last months about how to do precise datetime math more than a few years in the past and in the future. I suggest you join the list if you are interested in help developing such a module. Flávio S. Glock
On Tue Dec 02 09:09:39 2008, andy.switala@gmail.com wrote: Show quoted text
> Hi, > > The following applies to DateTime 0.45 on Perl 5.10.0 (Win32). > > This is wrong: > > $ perl -mDateTime -e "print ((DateTime->new(year => 1970, \ > time_zone => 'UTC')->subtract_datetime_absolute(DateTime->new(year \ > => 1583, time_zone => 'UTC')))->seconds)" > 12212553600
Is it? Eyeballing it, it seems right to me. Show quoted text
> $ perl -mDateTime -e "print DateTime->new(year => 1583, \ > time_zone => 'UTC')->add(seconds=>12212553600)" > 1582-12-31T23:59:59
This works on my system. Show quoted text
> As a work-around, my code has to deal with three separate cases: > 1. Prior to 1972 - before leap seconds were introduced, so convert delta > seconds > 2**32 to delta weeks and days < 2**32 (so far). > 2. 1972 to 6 months from now - delta seconds fits in a 32 bit integer > 3. More than 6 months from now - leap seconds are unknown, so delta > seconds are uncertain, might as well convert to delta weeks and days. > > ^^^ Not having to deal with this sort of thing is the reason one uses a > date library in the first place. DateTime is otherwise an excellent
module. Show quoted text
>
I think the key here is that my system is 64 bit. Given that nowadays 32 bit is well on its way out, I don't think it's unreasonable to suggest that you if you need to do math like this, you should make sure you have a 64-bit capable Perl. Alternately, I think it'd be possible to tweak the code to make it work even on a 32-bit Perl. Internally, Perl can use its NV type to effectively emulate 64 bit integers. However, the DateTime code uses the IV type instead, which is limited by the system's integer size. Patches to make this work would be welcome.