Req #55240 [Opn->Csd]: DateTime::createFromFormat with format 'd.m.Y Gi' returns wrong date

From: Date: Tue, 28 Sep 2021 09:26:45 +0000
Subject: Req #55240 [Opn->Csd]: DateTime::createFromFormat with format 'd.m.Y Gi' returns wrong date
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-236881@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=55240&edit=1 ID: 55240 Updated by: cmb@php.net Reported by: m dot strucken at binserv dot de Summary: DateTime::createFromFormat with format 'd.m.Y Gi' returns wrong date -Status: Open +Status: Closed Type: Feature/Change Request Package: Date/time related Operating System: Windows Server 2008 R2 PHP Version: 5.3.6 -Assigned To: +Assigned To: cmb Block user comment: N Private report: N New Comment: As of PHP 5.3.9, this fails[1], and I think we can leave it at that. [1] <https://3v4l.org/XRpio> Previous Comments: ------------------------------------------------------------------------ [2014-01-09 17:26:45] brian at brianhogg dot ca This is similar to this example: <?php $date = DateTime::createFromFormat('MjY', 'Jan92014'); var_dump($date); var_dump(DateTime::getLastErrors()); which outputs: class DateTime#1 (3) { public $date => string(19) "0014-04-02 18:24:29" public $timezone_type => int(3) public $timezone => string(13) "Europe/Zurich" } array(4) { 'warning_count' => int(1) 'warnings' => array(1) { [8] => string(27) "The parsed date was invalid" } 'error_count' => int(0) 'errors' => array(0) { } } Technically you could know where to stop based on the fact that Y is 4 digits and M is 3 characters, but understand that parsing left-to-right makes this difficult. ------------------------------------------------------------------------ [2011-11-26 16:40:47] derick@php.net Hi! I've had a look at this, and now I can tell you what happens. Without the delimiter, the 800 gets parsed as 80 hours, 0 minutes. If you add 80 hours to 11.11.2009, that means 3 days, 8 hours, you get 14.11.2009, 8am. If you call DateTime::getLastError, you see it shows a warning: derick@whisky:~$ cat /tmp/test.php <?php $dt = DateTime::createFromFormat( 'd.m.Y Gi', '11.11.2009 800' ); var_dump($dt); var_dump(DateTime::getLastErrors()); echo $dt->format( 'd.m.Y G i' ); ?> derick@whisky:~$ php /tmp/test.php class DateTime#1 (3) { public $date => string(19) "2009-11-14 08:00:00" public $timezone_type => int(3) public $timezone => string(13) "Europe/London" } array(4) { 'warning_count' => int(1) 'warnings' => array(1) { [14] => string(27) "The parsed time was invalid" } 'error_count' => int(0) 'errors' => array(0) { } } 14.11.2009 8 00 derick@whisky:~$ The parser for "G" parses up to 2 characters, and it doesn't know how to stop if it encounters something too high. I'm looking at how I can changes this, but still not break BC in any form. I've changed the bug's status to FR now. cheers, Derick ------------------------------------------------------------------------ [2011-07-19 11:11:45] m dot strucken at binserv dot de Description: ------------ Having a date without a delimiter between hour and minute and the hour without leading zero, the returned date from DateTime::createFromFormat() is incorrect Test script: --------------- $dt = DateTime::createFromFormat( 'd.m.Y Gi', '11.11.2009 800' ); echo $dt->format( 'd.m.Y Gi' ); Expected result: ---------------- 11.11.2009 800 Actual result: -------------- 14.11.2009 800 ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=55240&edit=1

« previous php.bugs (#236881) next »