|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2018-12-30 16:34 UTC] girgias@php.net
-Package: Documentation problem
+Package: Date/time related
[2022-06-02 11:10 UTC] git@php.net
[2022-06-02 11:10 UTC] git@php.net
-Status: Open
+Status: Closed
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Nov 06 07:00:01 2025 UTC |
Description: ------------ Copied from internals discussion. --------- strtotime() handles date/time edge cases and produces reasonable timestamp in some cases. $ php -r "echo date('Y-m-d H:i:s',strtotime('00-01-01 24:00:00'));" 2000-01-02 00:00:00 $ php -r "echo date('Y-m-d H:i:s',strtotime('03-02-29 00:00:00'));" 2003-03-01 00:00:00 $ php -r "echo date('Y-m-d H:i:s',strtotime('03-02-28 23:59:60'));" 2003-03-01 00:00:00 It returns FALSE for larger values exceeds edge cases. For example, $ php -r "var_dump(strtotime('03-02-32 00:00:00'));" bool(false) Somehow it does not accept 13 month while it is edge case. $ php -r "var_dump(strtotime('03-13-30 00:00:00'));" bool(false) It does not accept day 32 while it accepts 2/31. $ php -r "var_dump(strtotime('03-01-32 00:00:00'));" bool(false) $ php -r "var_dump(strtotime('03-02-31 00:00:00'));" int(1046617200) 25 hour/60 minutes is invalid also. $ php -r "var_dump(strtotime('03-02-31 00:60:00'));" bool(false) $ php -r "var_dump(strtotime('03-02-31 25:00:00'));" bool(false) It seems edge case handling is inconsistent. On Wed, Sep 9, 2015 at 1:31 AM, Derick Rethans <derick@php.net> wrote: > Currently, it works as follows by design: > > - the parser, allows for each unit (year, month, day, hour, minute, > second) the full range of values. For a year that's just 4 digits, for > a month that's 0-12, day is 0-31 and for hour and minute it's 0-59. > > - 60 is allowed for seconds, as sometimes date strings with that > leapsecond do show up. But PHP implements Unix time where "60" is not > a valid second number and hence it overflows. There is some more > background information at http://drck.me/leapsec-6ye > > - strtotime() returns false if any number is outside of the ranges, and > new DateTime() throws an exception. > > - the parser is dumb, and doesn't do any checks to make it faster (and > more generic) > > - *but*, there is an additional check if you pass in an invalid date > (like your suggested $strict): > > $ php -r '$res = date_parse("2015-09-31"); var_dump($res["warnings"]);' > > array(1) { > [11] => > string(27) "The parsed date was invalid" > } > > - It is already possible to handle the edge cases, but then you need to > supply the right format. Otherwise there are too many possible > confusing and unintuitive results coming out of the parser: > > php -r '$res = date_create_from_format("Y-m-d", "2015-09-34"); var_dump($res);' > > class DateTime#1 (3) { > public $date => > string(26) "2015-10-04 17:24:43.000000" > public $timezone_type => > int(3) > public $timezone => > string(13) "Europe/London" > } > > - We can't add a second argument to strtotime(), because it already > exists. > > - Having a "strict" option to strtotime() does also not work, as that > would mean two distinct parsing routines. > > With all those concerns, as well as functionality to handle edge cases > in place, I do not think we should change anything. Thank you for detailed explanation. I'm OK with current design/API. How about add documentation for more precise date/time parsing and handling to strtotime() manual page? One concern is "0000-00-00" date. MySQL uses it as invalid date and strtotime() produces non intuitive result. It should be added to the document also.