Doc #72471 [Opn->Csd]: Docs to explain how adding/subtracting dates work

From: Date: Thu, 23 Jun 2016 16:15:30 +0000
Subject: Doc #72471 [Opn->Csd]: Docs to explain how adding/subtracting dates work
References: 1  Groups: php.doc.bugs 
Request: Send a blank email to doc-bugs+get-13596@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=72471&edit=1 ID: 72471 Updated by: cmb@php.net Reported by: requinix@php.net Summary: Docs to explain how adding/subtracting dates work -Status: Open +Status: Closed Type: Documentation Problem Package: Date/time related PHP Version: Irrelevant -Assigned To: +Assigned To: cmb Block user comment: N Private report: N New Comment: This bug has been fixed in the documentation's XML sources. Since the online and downloadable versions of the documentation need some time to get updated, we would like to ask you to be a bit patient. Thank you for the report, Damian, and for helping us make our documentation better. I've changed the first two examples to transition away from DST to avoid having to document the mentioned bug, or to give a false output example. Please review the commit. Previous Comments: ------------------------------------------------------------------------ [2016-06-23 16:12:03] cmb@php.net Automatic comment from SVN on behalf of cmb Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=339459 Log: Fix #72471: Docs to explain how adding/subtracting dates work ------------------------------------------------------------------------ [2016-06-22 20:49:21] requinix@php.net The output on the third example is clearly wrong: should say 2015 for the first half. Copy/paste fail. ------------------------------------------------------------------------ [2016-06-22 20:47:41] requinix@php.net Description: ------------ I've seen many bugs that stem from how modifying dates, such as by strtotime or DateTime::modify, can cause unexpected results. Mostly due to DST transitions and how months have different numbers of days (looking at you, February). Such as bug #72470 just now. PHP tackles the problem in a fairly 'nix-standardized way that is not always obvious to a developer, and I think there should be documentation explaining how it works. The three main topics are: 1. DateTime::add/sub add intervals which cover elapsed time, so adding PT24H over a DST transition will appear to add 23/25 hours (for most timezones). Note that the below code should give that output but doesn't due to bug #72398. <?php $dt = new DateTime("2016-03-13 00:00:00", new DateTimeZone("America/New_York")); echo "Start: ", $dt->format("Y-m-d H:i:s P"), "\n"; // 2016-03-13 00:00:00 -05:00 $dt->add(new DateInterval("PT24H")); echo "End: ", $dt->format("Y-m-d H:i:s P"), "\n"; // 2016-03-14 01:00:00 -04:00 ?> 2. DateTime::modify and strtotime will increment or decrement individual component values, so adding +24 hours over a DST transition will add exactly 24 hours as seen in the date/time string (unless the start or end time is on a transition point). <?php $dt = new DateTime("2016-03-13 00:00:00", new DateTimeZone("America/New_York")); echo "Start: ", $dt->format("Y-m-d H:i:s P"), "\n"; // 2016-03-13 00:00:00 -05:00 $dt->modify("+24 hours"); echo "End: ", $dt->format("Y-m-d H:i:s P"), "\n"; // 2016-03-14 00:00:00 -04:00 ?> 3. Adding or subtracting times can over- or underflow dates, like where January 31st + 1 month will result in March 2nd (leap year) or 3rd (normal year). For that example I suggest also giving a solution to how one can "prevent" the overflow and only get the last day of the month. <?php echo "Normal year:\n"; // February has 28 days $dt = new DateTime("2015-01-31 00:00:00", new DateTimeZone("America/New_York")); echo "Start: ", $dt->format("Y-m-d H:i:s P"), "\n"; // 2016-01-31 00:00:00 -05:00 $dt->modify("+1 month"); echo "End: ", $dt->format("Y-m-d H:i:s P"), "\n"; // 2016-03-03 00:00:00 -05:00 echo "Leap year:\n"; // February has 29 days $dt = new DateTime("2016-01-31 00:00:00", new DateTimeZone("America/New_York")); echo "Start: ", $dt->format("Y-m-d H:i:s P"), "\n"; // 2016-01-31 00:00:00 -05:00 $dt->modify("+1 month"); echo "End: ", $dt->format("Y-m-d H:i:s P"), "\n"; // 2016-03-02 00:00:00 -05:00 ?> ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=72471&edit=1

« previous php.doc.bugs (#13596) next »