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

From: Date: Wed, 22 Jun 2016 20:47:46 +0000
Subject: Doc #72471 [NEW]: Docs to explain how adding/subtracting dates work
Groups: php.doc.bugs 
Request: Send a blank email to doc-bugs+get-13590@lists.php.net to get a copy of this message
From: requinix Operating system: PHP version: Irrelevant Package: Date/time related Bug Type: Documentation Problem Bug description:Docs to explain how adding/subtracting dates work 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 bug report at https://bugs.php.net/bug.php?id=72471&edit=1 -- Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=72471&r=trysnapshot54 Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=72471&r=trysnapshot55 Try a snapshot (trunk): https://bugs.php.net/fix.php?id=72471&r=trysnapshottrunk Fixed in SVN: https://bugs.php.net/fix.php?id=72471&r=fixed Fixed in release: https://bugs.php.net/fix.php?id=72471&r=alreadyfixed Need backtrace: https://bugs.php.net/fix.php?id=72471&r=needtrace Need Reproduce Script: https://bugs.php.net/fix.php?id=72471&r=needscript Try newer version: https://bugs.php.net/fix.php?id=72471&r=oldversion Not developer issue: https://bugs.php.net/fix.php?id=72471&r=support Expected behavior: https://bugs.php.net/fix.php?id=72471&r=notwrong Not enough info: https://bugs.php.net/fix.php?id=72471&r=notenoughinfo Submitted twice: https://bugs.php.net/fix.php?id=72471&r=submittedtwice register_globals: https://bugs.php.net/fix.php?id=72471&r=globals PHP 4 support discontinued: https://bugs.php.net/fix.php?id=72471&r=php4 Daylight Savings: https://bugs.php.net/fix.php?id=72471&r=dst IIS Stability: https://bugs.php.net/fix.php?id=72471&r=isapi Install GNU Sed: https://bugs.php.net/fix.php?id=72471&r=gnused Floating point limitations: https://bugs.php.net/fix.php?id=72471&r=float No Zend Extensions: https://bugs.php.net/fix.php?id=72471&r=nozend MySQL Configuration Error: https://bugs.php.net/fix.php?id=72471&r=mysqlcfg

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