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

From: Date: Wed, 22 Jun 2016 20:49:22 +0000
Subject: Doc #72471 [Opn]: Docs to explain how adding/subtracting dates work
References: 1  Groups: php.doc.bugs 
Request: Send a blank email to doc-bugs+get-13591@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: requinix@php.net Reported by: requinix@php.net Summary: Docs to explain how adding/subtracting dates work Status: Open Type: Documentation Problem Package: Date/time related PHP Version: Irrelevant Block user comment: N Private report: N New Comment: The output on the third example is clearly wrong: should say 2015 for the first half. Copy/paste fail. Previous Comments: ------------------------------------------------------------------------ [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 (#13591) next »