php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73086 createFromFormat method wrongly parses rfc2616 date
Submitted: 2016-09-15 07:45 UTC Modified: 2017-02-12 18:17 UTC
From: simon at programujem dot eu Assigned:
Status: Not a bug Package: Date/time related
PHP Version: 7.0.10 OS: Windows
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: simon at programujem dot eu
New email:
PHP Version: OS:

 

 [2016-09-15 07:45 UTC] simon at programujem dot eu
Description:
------------
The method createFromFormat of both classes \DateTime and \DateTimeImmutable incorrectly parses rfc2616 formatted date used in, but not limited to, Last-Modified and If-Modified-Since headers as defined by w3.

Using the following format: 'D, d M Y H:i:s e' it does actually parse the passed rfc2616 string but the days do not match for some dates, eg. trying to parse the date 'Thu, 4 Sep 2016 07:12:28 GMT' will result in \DateTime instance or \DateTimeImmutable respectively of not the fourth September but 8th instead.

The targeted PHP version is 7.0.10 running on Windows 7 x64, but the problem has been noticed in PHP 5.6.25 (running on a Linux distribution) as well.

Test script:
---------------
<?php

$format = 'D, d M Y H:i:s e';

$output = (\DateTimeImmutable::createFromFormat($format, 'Thu, 1 Sep 2016 07:12:28 GMT'))->format(\DateTime::ATOM);
print_r($output.'<br>'); // 2016-09-01T07:12:28+00:00

$output = (\DateTimeImmutable::createFromFormat($format, 'Thu, 2 Sep 2016 07:12:28 GMT'))->format(\DateTime::ATOM);
print_r($output.'<br>'); // 2016-09-08T07:12:28+00:00

$output = (\DateTimeImmutable::createFromFormat($format, 'Thu, 3 Sep 2016 07:12:28 GMT'))->format(\DateTime::ATOM);
print_r($output.'<br>'); // 2016-09-08T07:12:28+00:00

$output = (\DateTimeImmutable::createFromFormat($format, 'Thu, 4 Sep 2016 07:12:28 GMT'))->format(\DateTime::ATOM);
print_r($output.'<br>'); // 2016-09-08T07:12:28+00:00

$output = (\DateTimeImmutable::createFromFormat($format, 'Thu, 12 Sep 2016 07:12:28 GMT'))->format(\DateTime::ATOM);
print_r($output.'<br>'); // 2016-09-15T07:12:28+00:00

$output = (\DateTimeImmutable::createFromFormat($format, 'Thu, 13 Sep 2016 07:12:28 GMT'))->format(\DateTime::ATOM);
print_r($output.'<br>'); // 2016-09-15T07:12:28+00:00

$output = (\DateTimeImmutable::createFromFormat($format, 'Thu, 14 Sep 2016 07:12:28 GMT'))->format(\DateTime::ATOM);
print_r($output.'<br>'); // 2016-09-15T07:12:28+00:00

$output = (\DateTimeImmutable::createFromFormat($format, 'Thu, 15 Sep 2016 07:12:28 GMT'))->format(\DateTime::ATOM);
print_r($output.'<br>'); // 2016-09-15T07:12:28+00:00

Expected result:
----------------
2016-09-01T07:12:28+00:00
2016-09-02T07:12:28+00:00
2016-09-03T07:12:28+00:00
2016-09-04T07:12:28+00:00
2016-09-12T07:12:28+00:00
2016-09-13T07:12:28+00:00
2016-09-14T07:12:28+00:00
2016-09-15T07:12:28+00:00

Actual result:
--------------
2016-09-01T07:12:28+00:00
2016-09-08T07:12:28+00:00
2016-09-08T07:12:28+00:00
2016-09-08T07:12:28+00:00
2016-09-15T07:12:28+00:00
2016-09-15T07:12:28+00:00
2016-09-15T07:12:28+00:00
2016-09-15T07:12:28+00:00

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-09-15 10:27 UTC] cmb@php.net
There is no 'Thu, 4 Sep 2016 07:12:28 GMT', so I see three
possible solutions:

 1. fail
 2. ignore the weekday
 3. ignore the day

Obviously, the date parser chooses option (3). In my opinion, that
is fine, because it's more liberal than (1), but probably it would
be good to emit a notice or warning in this case.
 [2016-09-15 10:58 UTC] simon at programujem dot eu
I feel really dumb right now. I totally didn't realize I need to change the name of the day as well as it felt more natural to me to ignore the weekday rather than the day (which is what PHP does).

A notice or a warning might be a good idea, though, to let the developer explicitly know that yes, the method did indeed parse the data but something was slightly wrong during the process.

Thanks for the reply.
 [2017-02-12 18:17 UTC] derick@php.net
-Status: Open +Status: Not a bug
 [2017-02-12 18:17 UTC] derick@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

This is expected bahaviour, and actually a feature.

Thu, 2 Sep 2016 07:12:28 GMT

gets parsed as

2016-09-02 07:12:28 Tuesday

As Sept 2nd, is not a Tuesday, the code moves it forwards to the first Tuesday it finds. 

This is documented under "Day-based Notations" / "Dayname" at http://php.net/manual/en/datetime.formats.relative.php
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 21:01:27 2024 UTC