|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76770 'U' modifier in 'datetime::createFromFormat' adds seconds to other specifiers
Submitted: 2018-08-20 12:08 UTC Modified: 2020-12-23 15:49 UTC
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (100.0%)
From: bjoern dot fischer at dezem dot de Assigned: derick (profile)
Status: Closed Package: Date/time related
PHP Version: Irrelevant OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Bug Type:
From: bjoern dot fischer at dezem dot de
New email:
PHP Version: OS:


 [2018-08-20 12:08 UTC] bjoern dot fischer at dezem dot de
This problem apparently exists on all PHP versions where 'datetime' is present.

The problem can be reproduced here:

The given example should create the time-stamp '3600' but the actual result is '7200'.

It appears as if the value of 'U' is just added to other date/time information.
However since 'U' represents a Unix-time-stamp, it itself fully specifies the time. It should not be changed if other format specifiers are present.

Test script:
var_dump(datetime::createFromFormat('!U H', '3600 01')->getTimestamp());

Expected result:
Using 'U' with 'datetime::createFromFormat' should result in a datetime object that returns the value for 'U' as a timestamp.

Actual result:
Using 'U' with 'datetime::createFromFormat' adds the value for 'U' and other date/time components together, resulting in incorrect time-stamps.


Add a Patch

Pull Requests

Pull requests:

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2018-08-20 12:35 UTC]
-Package: *General Issues +Package: Date/time related
 [2018-08-20 13:53 UTC]
-Status: Open +Status: Feedback
 [2018-08-20 13:53 UTC]
What should this return (given Aug 20 is a Monday):

DateTime::createFromFormat("!Y-m-d H:i:s D", "2018-08-20 12:34:56 Tuesday")
 [2018-08-21 07:15 UTC] bjoern dot fischer at dezem dot de
Hello requinix.

I don't seem to understand your question. The code you posted has no 'U' modifier in it and the reported bug only appears when using that modifier.
 [2018-08-21 08:50 UTC]
-Status: Feedback +Status: Open
 [2018-08-21 08:50 UTC]
I know, but I still want to know your opinion. Because I would argue that using 'U' or using a full 'Y-m-d H:i:s' should both work the same way when it comes to something that "fully specifies the time".

  DateTime::createFromFormat("!Y-m-d H:i:s D", "2018-08-20 12:34:56 Tuesday")
becomes either 8-20 (Monday) or 8-21 (Tuesday), depending. If it's the former then we've established a consistent behavior and I can understand it. If it's the latter then I think that's inconsistent and it implies 'U' is something unique and magical.

Either way I don't think we can change this behavior, if only for the simple reason that changing 'U' (at least) to work like this would break any existing code that wants to do something like
  DateTime::createFromFormat("!U D", "{$timestamp} Tuesday")
which would, hypothetically, be there to start with one timestamp and then deliberately modify it - much like how strtotime() is often used.
 [2018-08-21 10:13 UTC] bjoern dot fischer at dezem dot de
Ah. Now I get your concern.

I think this is a separate problem.
In my opinion, your example should just result in an error as the provided date/time-string is inconsistent. (I'm actually currently implementing a wrapper around 'datetime' that  does this.)
However preferring the first or the last of those two redundant specifiers would both be understandable to me.
I don't really understand yet why the former should be preferred.

In the issue I describe, something different happens.
There we have a redundant time format where the specified date/time-string is actually consistent.
But instead  of just having the components accepted as consistent, they are added together.

I think the use case that you describe should not be the point of 'datetime::createFromFormat()'. We have 'datetime::modify()' for that.

Also this would be inconsistent with the rest of the behaviour of 'datetime::createFromFormat()'.
For example:
'var_dump(datetime::createFromFormat('!d j', '02 2')->getTimestamp());'
currently results in the time-stamp '86400'. By the reasoning you propose it should result in the time-stamp '172800'.
 [2018-08-21 10:37 UTC]
Okay, so after playing with it some more, it looks like 'U' is actually magical like I suggested it should not be.

With 'U', additional date parts are *added* to the timestamp. With other specifiers, date parts are *merged* with latter values overriding earlier values.

So I'm thinking either
a) 'U' should be fixed to not do that and to act like everything else, possibly with the last errors set, or
b) createFromFormat should reject the string entirely, and not just with 'U' but with other inconsistent strings

If it can't be changed then at least it needs to be documented.
 [2019-02-22 23:05 UTC]
The following pull request has been associated:

Patch Name: Fix #76770: Unix time parsed as non relative.
On GitHub:
 [2020-01-20 17:34 UTC]
-Assigned To: +Assigned To: derick
 [2020-12-23 15:49 UTC]
-Status: Assigned +Status: Closed
 [2020-12-23 15:49 UTC]
This issue is fixed with the latest timelib, and as such as of PHP
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Jun 16 15:01:28 2024 UTC