I’ve been using PHP’s strtotime() method to accept a date field on a form. I love how powerful it is, in how it will accept “Tomorrow”, “Next Thursday”, or (supposedly) any date representation and convert it to the Unix timestamp.
It’s been working great — until yesterday. Someone entered “2-4-10” and instead of logging Feb 4th, 2010, it logged April 10, 2002! So it expected Y-M-D instead of M-D-Y.
I thought maybe the problem was just using a 2-digit year, so we tried again with “2-4-2010”. That logged April 2nd, 2010! At that point I just don’t understand what strtotime() is doing. PHP.net says it expects a US English date format. Why then would it assume D-M-Y?
Is there a way around this? Or do I have to stop using strtotime()?
Note: I just now did a test. When you use slashes instead of hyphen/dashes, it works fine, even with 2/4/10. Why on earth does that matter? And if that’s all it is, should I just run str_replace(“-“, “/”, $input) on the form input before passing it to strtotime()?
The – indicates an ISO Date:
03-02-01 => 1. february 2003 (ISO) 01.02.03 => 1. february 2003 (European) 02/01/03 => 1. february 2003 (US)
The behavior of
strtotime() is based largely on the GNU date input formats spec. But as powerful as it is, it shouldn’t be expected to read minds. Allowing free-form user date input is asking for perpetual trouble.
I had this problem and solved it by doing exactly what you suggested – do a
str_replace on the user-entered date to replace the dashes with slashes. This prevents
strtotime from using an ISO date and solves the problem.
strtotime is by its very nature fuzzy, so you can’t assume that it will always do what you want. If you enter 2010-04-02 then you would expect that to return 2nd April 2010, which is what strottime is trying to do. Running an str_replace from hyphens to slashes might mean that people entering in that format get the wrong date.
If you’re running PHP 5.3 or above, consider date_parse_from_format() or for PHP 5.1 and above on Unix consider strptime(). Both functions take a format, so remove potential ambiguity (if you tell users what format you are expecting – if you’re running an international site and have a text box labelled date which the user enters 2/4/2010 into then there is no way to know what their intended date is).