Doc #72471 [NEW]: Docs to explain how adding/subtracting dates work
| From: | requinix@php.net | 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