PHP strtotime assumptions with European and American date formats

PHP date functions really are the ultimate gift that keeps on giving. The primary problem with them is a grandiose assumption that date formats are going to be American format. There is typically no mechanism to indicate alternate format. At minimum a simple parameter would work Eu/US/ISO; clearly things are not that simple in real life, and so a more sophisticated solution should be encouraged, but to continue to assume that your developer audience is US-centric is a little ostrich-like.

BlogIt has had a persistent, but sporadic problem almost since day one, where saving a blog entry would cause the date to be stored wildly incorrectly. So "11-08-2010" would get stored as "30-Jan-2017". I spent the better 10 hours working with someone who was having a problem with BlogIt, only to discover an hidden assumption in strtotime.

The humble strtotime, takes a date, and returns a Unix time string. It accepts a huge number of inbound formats, and is very flexible. Rather than providing a parameter, or some means of allowing the developer to indicate a preference in that decision process, strtotime makes some pretty odd, minimally documented, and rather obscure choices when there might be more than one way to interpret an inbound date.

After much research, and debugging, I discovered in a small comment on the PHP strtotime manual noting that when you pass a date format into strtotime certain assumptions are made about the separator that is used within the date format. In this case, BlogIt uses a hyphen "11-08-2010". strtotime assumes that since we're using hyphens, the date is an ISO format date, and thus tries to interpret the the date as year, month, day. Stackoverflow shows other delimiter assumptions:

  • 03-02-01 => 1 February 2003 (ISO)
  • 01.02.03 => 1 February 2003 (European)
  • 02/01/03 => 1 February 2003 (US)

On their own, these assumptions are pretty logical. If they were documented. And if there was a way to override the assumption, when we know a specific date format is going in. Now I know how strtotime behaves, BlogIt can pre-format the inbound date to something that strtotime will be handle correctly. Developer be ware -- date delimiters have hidden meanings.