Skip links

DateTime createFromFormat without time

August 12, 2015 at 9:08 AM - by Freek Lijten - 6 comments

Tags:

This is just a quick word of warning. I recently had a bug where two DateTime objects that were created with the same date were inequal to eachother. It turned out that this was a difference between the normal __construct() and createFromFormat. This is actually documented behaviour but since people might be searching for this problem, this post might help.

tl;dr

When you use createFromFormat use a ! in front of your format to have all time parts set to 0 (Epoch technically, but then you should read :p )

$A = new DateTime('2015-08-10');
$B = DateTime::createFromFormat('Y-m-d', '2015-08-10');
var_dump($A == $B);

I expected the dumped result to be true. Both where created with the same date and without time after all. Oddly enough (for me, at that time) I noticed that the result of this was false. The object created with createFromFormat did have a time, viz. the current time. Run this code at 12:31 and the time will be 12:31 for object B.

Since the constructor does not add any time and defaults to all zeroes, it all of a sudden makes sense these two are not equal. This is documented behaviour as one can see here when you scroll to the format explanation. To make sure that the current time is not copied you must preceed your format with an exalamation mark. In this case the values from unix epoch (the start of unix time) will be copied. Since the time parts of unix epoch are all zeroes there effectively will be no time set:

// Without !
var_dump(DateTime::createFromFormat('Y-m-d', '2015-08-10'));

/**
object(DateTime)#1 (3) {
  ["date"]=>
  string(26) "2015-08-10 15:54:44.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(16) "Europe/Amsterdam"
}
*/

// With !
var_dump(DateTime::createFromFormat('!Y-m-d', '2015-08-10'));

/**
object(DateTime)#1 (3) {
  ["date"]=>
  string(26) "2015-08-10 00:00:00.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(16) "Europe/Amsterdam"
}
*/

Now this all not earh-shattering, but it surprised me and it might surprise others, I hope some of them might stumble upon this.

Share this post!

Comments

  1. Tristan BaileyTristan Bailey Wrote on August 19, 2015 at 9:27:21 AM

    Thanks for pointing this out, before when this was needed I was taking on the extra 00s to the creation call, concat with the var to be converted from a date. This makes more sense, though an extra ", true" or similar on the method might be more obvious.

  2. LaurentLaurent Wrote on April 5, 2016 at 10:48:53 AM

    Never saw that elsewhere, but precisely what I was looking for. Thanks a lot ! (though this should be added to PHP documentation !)

  3. Dennis PaulinoDennis Paulino Wrote on January 5, 2018 at 10:07:33 PM

    Thanks for this article, it was helpful! :)

  4. BrettBrett Wrote on March 26, 2018 at 8:35:48 PM

    Thanks, this was helpful.

  5. LuisLuis Wrote on May 4, 2018 at 2:39:59 PM

    Thanks! Your article saved my day :)

  6. JohnnyJohnny Wrote on July 11, 2018 at 10:12:53 AM

    Thanks! Very helpful information!

Leave a comment!

Italic and bold

*This is italic*, and _so is this_.
**This is bold**, and __so is this__.

Links

This is a link to [Procurios](http://www.procurios.nl).

Lists

A bulleted list can be made with:
- Minus-signs,
+ Add-signs,
* Or an asterisk.

A numbered list can be made with:
1. List item number 1.
2. List item number 2.

Quote

The text below creates a quote:
> This is the first line.
> This is the second line.

Code

A text block with code can be created. Prefix a line with four spaces and a code-block will be made.