Re: Error with the leap year
Michael G Schwern wrote: It does present a problem... how do you reliably say same date next year? Same date next year is exactly what the original poster asked DateTime for, by using the set_year method, and he got the correct answer: there isn't one. Presumably what he actually wanted was a year later, which is a different question. DateTime does support it: $dt-add(years=1); In the awkward case, it advances to March 1st: $ perl -MDateTime -lwe ' $dt=DateTime-new( year=2012, month=2, day=29, hour=12, minute=0, second=0, time_zone=UTC, ); $dt-add(years=1); print $dt-iso8601; ' 2013-03-01T12:00:00 Of course, it has the downside that year addition isn't associative: advancing from a February 29th by four years gives a different result from advancing by one year four times. You can't add 365 days because that falls afoul of the leap year problem. You can ask DateTime for that too: $dt-add(days=365); It's nicer, in that day addition *is* associative. Of course, a quarter of the time (when the 365 days spans a leap day), the 365-days-later won't be the same-date-next-year. Is that what you mean by the leap year problem? -zefram
Re: Error with the leap year
On Fri, Mar 02, 2012 at 10:17:08AM +, Zefram wrote: In the awkward case, it advances to March 1st: ... Of course, it has the downside that year addition isn't associative: advancing from a February 29th by four years gives a different result from advancing by one year four times. ... It's nicer, in that day addition *is* associative. Of course, a quarter of the time (when the 365 days spans a leap day), the 365-days-later won't be the same-date-next-year. Is that what you mean by the leap year problem? Reasons Why You Should Never Write Custom Date / Time Handling Code Yourself Vol. 1 No. 1 - 3... Matthew
Re: Error with the leap year
On Mar 1, 2012, at 17:14, jonathan.pey...@ubs.com wrote: If the date for $dt is 20120229, the following produces an error! $dt-set_year($dt1-year + 1); Invalid day of month (day = 29 - month = 2) at /sbcimp/run/pd/cpan/5.8.8-2006.03/lib/DateTime.pm line 170 DateTime::new('undef', 'hour', 0, 'second', 0, 'month', 2, 'locale', 'DateTime::Locale::en_US=HASH(0x8e15400)', ...) called at /sbcimp/run/pd/cpan/\ 5.8.8-2006.03/lib/DateTime.pm line 1507 DateTime::set('undef', 'year', 2013) called at /sbcimp/run/pd/cpan/5.8.8-2006.03/lib/DateTime.pm line 1514 Yeah. That was the subject of days of discussion as to what the right thing to do here was. Leap years are hard. This is what we decided was the right thing to do here. -- Rich Bowen, mobile edition
Re: Error with the leap year
On Fri, Mar 2, 2012 at 10:06 PM, Rich Bowen rbo...@rcbowen.com wrote: On Mar 1, 2012, at 17:14, jonathan.pey...@ubs.com wrote: If the date for $dt is 20120229, the following produces an error! $dt-set_year($dt1-year + 1); Invalid day of month (day = 29 - month = 2) at /sbcimp/run/pd/cpan/5.8.8-2006.03/lib/DateTime.pm line 170 DateTime::new('undef', 'hour', 0, 'second', 0, 'month', 2, 'locale', 'DateTime::Locale::en_US=HASH(0x8e15400)', ...) called at /sbcimp/run/pd/cpan/\ 5.8.8-2006.03/lib/DateTime.pm line 1507 DateTime::set('undef', 'year', 2013) called at /sbcimp/run/pd/cpan/5.8.8-2006.03/lib/DateTime.pm line 1514 Yeah. That was the subject of days of discussion as to what the right thing to do here was. Leap years are hard. This is what we decided was the right thing to do here. -- Rich Bowen, mobile edition The problem is pretty much identical to adding 1 month to a month with more days than the next (i.e. any month with 31 days except January and July). The behaviour should be the same, which it is. Regards Myfanwy White
RE: Error with the leap year
If that is what was decided, that's fine. However, it should be mentioned in the documentation. Thank you, Jonathan From: Rich Bowen [mailto:rbo...@rcbowen.com] Sent: Friday, March 02, 2012 6:06 AM To: Peyser, Jonathan Cc: datetime@perl.org Subject: Re: Error with the leap year On Mar 1, 2012, at 17:14, jonathan.pey...@ubs.com wrote: If the date for $dt is 20120229, the following produces an error! $dt-set_year($dt1-year + 1); Invalid day of month (day = 29 - month = 2) at /sbcimp/run/pd/cpan/5.8.8-2006.03/lib/DateTime.pm line 170 DateTime::new('undef', 'hour', 0, 'second', 0, 'month', 2, 'locale', 'DateTime::Locale::en_US=HASH(0x8e15400)', ...) called at /sbcimp/run/pd/cpan/\ 5.8.8-2006.03/lib/DateTime.pm line 1507 DateTime::set('undef', 'year', 2013) called at /sbcimp/run/pd/cpan/5.8.8-2006.03/lib/DateTime.pm line 1514 Yeah. That was the subject of days of discussion as to what the right thing to do here was. Leap years are hard. This is what we decided was the right thing to do here. -- Rich Bowen, mobile edition Visit our website at http://www.ubs.com This message contains confidential information and is intended only for the individual named. If you are not the named addressee you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately by e-mail if you have received this e-mail by mistake and delete this e-mail from your system. E-mails are not encrypted and cannot be guaranteed to be secure or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete, or contain viruses. The sender therefore does not accept liability for any errors or omissions in the contents of this message which arise as a result of e-mail transmission. If verification is required please request a hard-copy version. This message is provided for informational purposes and should not be construed as a solicitation or offer to buy or sell any securities or related financial instruments. UBS reserves the right to retain all messages. Messages are protected and accessed only in legally justified cases.
RE: Error with the leap year
On Fri, 2 Mar 2012, jonathan.pey...@ubs.com wrote: If that is what was decided, that's fine. However, it should be mentioned in the documentation. A doc patch would be welcome. However, I will point out that what you were doing is weird. If you want to do DateTime math, you need to use -add and -subtract (although these can _also_ come up with invalid datetimes in the face of DST changes). The DST issue is documented pretty clearly in the How Datetime Math Works section of the docs. -dave /* http://VegGuide.org http://blog.urth.org Your guide to all that's veg House Absolute(ly Pointless) */
Re: Error with the leap year
I agree with the idea of adding caveats to the POD for using the set_* methods. I had a colleague who tried to add 4 days to a DateTime like so: $dt-set_day($dt-day + 4) And it worked fine in the beginning of the month. This is similar to the erroneous use of set_year below. Of course, no matter how clearly or thoroughly a document is written there will always be someone that will misread and misuse it. On Mar 2, 2012, at 12:32 PM, Michael G Schwern wrote: On 2012.3.2 11:17 AM, Dave Rolsky wrote: However, I will point out that what you were doing is weird. If you want to do DateTime math, you need to use -add and -subtract (although these can _also_ come up with invalid datetimes in the face of DST changes). The DST issue is documented pretty clearly in the How Datetime Math Works section of the docs. While there may be a section about DateTime math, there's little in the docs about set caveats. It's non-obvious that $dt-set_year( $dt-year + 1 ) is significantly different than $dt-add( years = 1 ) or that there's anything wrong with using set in that manner. There needs to be a warning or pointer in the set docs, because a user has no motivation to fish further. I'd suggest a section about when to use set_* and when to use add_* and what their caveats are. Put pointers to it in the set_* and add_* documentation. -- 10. Not allowed to purchase anyone's soul on government time. -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army http://skippyslist.com/list/
Re: Error with the leap year
No configuration option is required in this case. The OP isn't having trouble with date math: that would have done what he wanted. He's using the set() method to set the object to a date that doesn't exist. Any behavior beyond an error would be incorrect. Should -new( year = 2012, month = 13, day = 42 ) assume you wanted Dec 31? No, it's an error. If you wanted 13 months, 42 days after Jan 1st 2012, then you should be using date math. Cheers! Rick Measham On 03/03/2012, at 5:14, Karen Etheridge p...@froods.org wrote: On Thu, Mar 01, 2012 at 08:26:13PM -0800, Michael G Schwern wrote: On 2012.3.1 2:14 PM, jonathan.pey...@ubs.com wrote: If the date for $dt is 20120229, the following produces an error! $dt-set_year($dt1-year + 1); Invalid day of month (day = 29 - month = 2) This error is correct, there is no Feb 29, 2013. It could return March 1, 2013... but then adding a year to Feb 29, 2012 and adding a year and a day give the same result which doesn't make sense. It does present a problem... how do you reliably say same date next year? This is very similar to the 'end_of_month_mode' feature in DateTime::Duration, which handles how (for example) Jan 30 + 1 month calculations are handled. Therefore, I would suggest a configuration option for handling how wrapping is done involving leap years. For that matter, leap seconds pose the same problem - if 00:00:60 is a leap second, how does one handle 00:00:60 + 1 minute? is it wrapped to the next minute (00:02:00), truncated (00:01:59), or...? -- #!/bin/perl -sp0777iX+d*lMLa^*lN%0]dsXx++lMlN/dsM0j]dsj $/=unpack('H*',$_);$_=`echo 16dio\U$kSK$/SM$n\EsN0p[lN*1 lK[d2%Sa2/d0$^Ixp|dc`;s/\W//g;$_=pack('H*',/((..)*)$/) . ... . Karen Etheridge, ka...@etheridge.ca GCS C+++$ USL+++$ P+++$ w--- M++ -- Message protected for iSite by MailGuard: e-mail anti-virus, anti-spam and content filtering.http://www.mailguard.com.au Click here to report this message as spam: https://login.mailguard.com.au/report/1EfBtCKdpY/2VzzLrnXo9n13n6snrZNTJ/0 -- Message protected for iSite by MailGuard: e-mail anti-virus, anti-spam and content filtering.http://www.mailguard.com.au
Re: Error with the leap year
no matter how clearly or thoroughly a document is written there will always be someone that will misread and misuse it. Or read the synopsis and decide the module's use is obvious without reading the documentation. I've been guilty of that with other modules. Perhaps we also need a warning at the top of the synopsis? Cheers! Rick Measham -- Message protected for iSite by MailGuard: e-mail anti-virus, anti-spam and content filtering.http://www.mailguard.com.au