Why PHP DateTime Rocks

Posted: 2012-08-01
Category: PHP

Working as a freelancer and contracter sometimes I come accross some code that is so terrible I have to laugh, then immediately tweet a screenshot for others to laugh. I think this is fairly healthy, but one reaction I get fairly often is "Yuck, PHP!". Really that should be "Yuck, PHP 4!" I've been using PHP since 4.0.1 and I remember it well. It was terrible. Whenever I see these chunks of code I like to see how clean I can make them with PHP 5.3 + code and DateTime has saved me a lot of lines.

DateTime is nothing new, but it's definitely under-used by many. It was made available in PHP 5.2.0 but got some of its best features until PHP 5.3.0. PHP 5.3.0 is pretty old now, but I learned about DateFormat::createFromFormat() after reading a new addition to PHP The Right Way: Date and Time.

Right, down to business.

First Offender

Format one crazy date into the standard MySQL date format.

Yuck. Using DateFormat::createFromFormat() we can ditch all of that code and instead just use this:

That's much better. But how about comparing dates?

Second Offender

Use mktime() to build them both into unix timestamps, then find out how many seconds right?

Did you just throw up in your mouth a little?

This sort of stuff is way too common and is totally unnecessary. If we want to stop pretending it's the 90's we could instead write it like this:

And there we have it!

We have cleaner, more readable, more reliable code. A perfect example of why you need to be upgrading to PHP 5.3 and a perfect example of PHP making massive leaps forward over time.

Update: Some people here and on Reddit are assuming I've never heard of strtotime() before. My mistake here was not being able to for-see EVERY possible angle for the article, which a common problem for bloggers.

So, why not use strtotime()? Firstly, using date('Y-m-d H:i:s', strtotime($strDate)) is the same as doing $date = new DateTime($strDate)->format('Y-m-d H:i:s') but of course with the objects you get more potentially useful methods than just an integer - which can lead to less code. Secondly, read the documentation

Dates in the m/d/y or d-m-y formats are disambiguated by looking at the separator between the various components: if the separator is a slash (/), then the American m/d/y is assumed; whereas if the separator is a dash (-) or a dot (.), then the European d-m-y format is assumed.

To avoid potential ambiguity, it's best to use ISO 8601 (YYYY-MM-DD) dates or DateTime::createFromFormat() when possible.

strtotime() is only useful if it KNOWS the format but what is happening here: 7/7/2011? Is that UK or US, because that could be m/d or d/m. When you are dealing with code that comes in from a wide array of random sources (horrible ADF feeds in this case) then the date formats are MENTAL, and telling it WHAT the data is means it can be parsed correctly.

Comments

Gravatar
Evert

2012-08-01

I think that your last example can only count the difference in seconds up to 59.

Gravatar
Marcelo Diniz

2012-08-01

Very good. I have learn more..... (I'm brazilian)
Tks

Gravatar

2012-08-01

Thanks Evert, that worked fine for my use-case (would never have been over a minute) but I added another approach.

Gravatar
Gustavo Rod. Baldera

2012-08-01

Yeah Datetime rocks! ...I had to imitate the behavior of DateTime::createFromFormat in PHP 5.2 for a client and it was a pain in ass

Gravatar
Victor Michnowicz

2012-08-01

It's also really nice to be able to use "#" to refer to multiple delimiters. I use that one a lot.

Gravatar
Ray

2012-08-01

Is there something wrong with using strtotime?

return date('Y-m-d H:m:s', strtotime($strDate));

Gravatar
Alan

2012-08-01

Or just use strtotime it is awesome.

Gravatar
Kiril

2012-08-01

Nope, you've got it all wrong. By "Yuck, PHP!" everyone includes version 5 and not without huge amount of reasons :)

Gravatar

2012-08-01

Oh hey I'd never heard of strtotime() before.

No, wait, yes I have.

strtotime() works if your date format happens to be one of those that can be automatically read. What happens if you have a UK v US format standoff, where nobody knows which way around the month or date is?

You can use DateTime to read ANY date, not just one that might look reasonable at the time.

Gravatar
Joshua Getner

2012-08-02

As i agree that there is alot of legacy code out there. But we all use to write code exactly like that 8 to 10 or so years ago. I'm much like you as i try to use the best code for the job and now days that is far superior to any code we could have wrote back then. But that fact is we would not be where we are today with writing and understanding code if we did not write horrible code first.

Gravatar
Dumubmudm

2012-08-03

example 1:
date('Y-m-d H:i:s', strtotime())

so you are 100% wrong in all the hyper-love towards whatever upthere

Gravatar
Jon Park

2012-08-03

@Joshua there's absolutely no need to write "horrible code" at all. With the likes of PHP: The Right Way (as mentioned in the OP) and great articles like this, spelling out best practice, the work has been done for you.

Even as someone who has been PHP-ing for many a year, the PHP renaissance community help shore up the weaker points in my own coding arsenal.

Great article Phil, I always held US date conversion mixups as a personal bugbear and was very relieved when I discovered the DateTime objects.

Gravatar
Chris

2012-08-04

Some of those bits of older code look strangely familiar to me.

Gravatar
Luke

2012-08-19

Shame you have to define the format which DateTime expects, either way I agree. FuelPHP's Date class works pretty much the same way. Good call for non Fuel sites.

Gravatar
Phil Sturgeon

2012-08-19

You don't HAVE to enter the format, but "createFromFormat" expects you to provide a format. It would be strangely named otherwise don't you think?

Read the docs, the DateTime class is very useful and the fact that this strange edge-case with a weird date format is so simple is what impresses me.

Gravatar
Montana Flynn

2012-08-20

I agree that PHP 5.3+'s DateTime is a huge improvement to how we used to deal with dates, but PHP, as a whole, seems rather archaic after joining the client side.

Gravatar

2012-08-20

Montana: Thats a fairly odd thing to say. JavaScript has always had AWFUL date and time handling. While I am a huge fan of EmberJS and have used it for a few projects, im not going around telling my clients to throw away all of their applications.

This was some legacy code taken from v1.0 of a project and improved before being brought over to v2.0 of the project, which is handling hundreds of websites and millions of users - I don't think anyone wanted to ditch it just because JS is a little trendier, and forcing JS frontends on technically inept clients is a pretty tough sell for any sales team.

PHP isn't going anywhere, and each iterative improvement and nice little gem I find like this I am going to post about. Hopefully that wont make people say "Err but what about JS" every single time, because that will get extremely tedious.

Gravatar
Ryan Marshall

2012-08-21

I'm a big fan of DateTime myself and have used it for a while now. For me it takes the pain out of date calculations and as you said makes things much nicer to look at.

In fact I just today came across an old example of my code that matches one of the ugly code examples you gave quite closely. ;)

Posting comments after three months has been disabled.