7

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()?

rhodesjason
  • 4,904
  • 9
  • 43
  • 59
  • 1
    Yes, attempting to normalize the date in some way before processing it with strtotime seems like a good idea to me. – JAL Feb 05 '10 at 13:46
  • Just wait until you try to use strtotime to parse *times*, then you'll be having some real Fun. (Think timezones, DST, etc.) –  Oct 12 '10 at 16:04

4 Answers4

7

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)
6

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.

GZipp
  • 5,386
  • 1
  • 22
  • 18
1

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.

Clayton
  • 6,089
  • 10
  • 44
  • 47
0

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).

thelem
  • 2,642
  • 1
  • 24
  • 34