3
echo date('r',strtotime("16 Dec, 2010")); //Tue, 16 Dec 2008 20:10:00 +0530
echo date('r',strtotime("16 Dec  2010")); //Sat, 16 Jan 2010 00:00:00 +0530

That's just wrong... Either it should fail or it should parse correctly. Do you know any robust natural language date/time parser in php? How do you parse natural language date time in php?

Edit:

var_dump(strtotime("16 Dec, abcd")); //bool(false)

"16 Dec, 2010" is either a valid GNU date input format or it is not. In the first case it should return the correct answer and in the second it should return false. This is what I mean by 'wrong'.

Edit:

The purpose is as hop guessed to accept a significant variety of user input.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
anshul
  • 5,945
  • 5
  • 24
  • 29
  • i'm afraid that's what you have to accept when using php –  Dec 18 '08 at 12:45
  • It is not wrong, it is just different from what you expect. 'respectable' parsers follow http://www.gnu.org/software/shishi/manual/html_node/Date-input-formats.html as does strtotime – Jacco Dec 18 '08 at 12:49
  • it's the "silently failing" part that is the problem. –  Dec 18 '08 at 13:03
  • It is not failing, it interprets your data differently from your expectations, but correct. – Jacco Dec 18 '08 at 13:18
  • interestingly enough, perl's Time::ParseDate gets the first one right, while interpreting 2010 in the second one as a time zone. at least it has options like FUZZY and WHOLE! –  Dec 18 '08 at 15:11
  • Jacco, I hope the edit I just made clears up my question. – anshul Dec 19 '08 at 10:14

5 Answers5

2

If you know in what format the time is represented in the string, you can use strptime() together with the appropriate format string to parse it. It will at least report an error when it cannot interpret the string according to the format.

This function exists in PHP 5.1.0 and up.

If you want to take arbitrary user input, you should offer clear and obvious feedback to the user, so that she can do something about a falsely interpreted date. Most of the time, there won't be a problem anyway and you can't ever catch all problematic cases (think American vs. European format).

  • Arbitrary user input is the idea. I do give clear feedback and auto-correct for european-american and now also the comma, but where does this chase end? I guess I will roll out my own parser when I get some leisure. – anshul Dec 19 '08 at 11:00
1

There is a Ruby class called Chronic that has the flexibility you need to handle convenient user input: http://chronic.rubyforge.org/

I'm sure you could just port it to PHP by replacing Ruby's Time with PHP's DateTime.

erjiang
  • 44,417
  • 10
  • 64
  • 100
1

It's not wrong, the data you're supplying is ambiguous - there is a world of difference.

Ambiguous data means the most you can reasonably expect from it is a 'best guess'. You might disagree with how it makes this best guess, but that's not 'wrong', that's just a different opinion on what is most likely. You can't expect any more than that without removing the ambiguity.

Further thoughts, mostly to hop's comments on the OP:

Silently failing is not an option - deciding when or not to silently fail is subject to the same rules, and will be thrown by the same ambiguities.

Which of the example strings is wrong and should silently fail? What about the guy next to you? Does he think the same one is wrong? What if you remove the context by not comparing them side by side?

The only thing 'wrong' here is expecting a function to be able to decipher an exact meaning from data that will always be subject to ambiguity... and this is just those examples, I haven't even got to dates yet :) (1/2/08 is the first of Feb? or the 2nd of Jan? 1908? 2008? 8?)

Right, that said, I'm off to write a function called 'is_this_art'...

JoeBloggs
  • 1,467
  • 9
  • 8
  • when you're done with the 'is_this_art' function will it be open soure ?-) – Jacco Dec 18 '08 at 13:40
  • What would be the point? My code is always perfect straight out of the box, and (myopinion === fact) is most definitely true. :) – JoeBloggs Dec 18 '08 at 14:18
  • 1
    nobody is saying that strtotime() should be perfect. what i'm trying to tell you is that PHP will get your hopes high and then crush you like a bug. try this: date('r', strtotime("2005-02-30")). and then tell mit that that date is ambiguous. i dare you. –  Dec 18 '08 at 16:13
  • +1 @hop... It is the unclear partial adherence to GNU Date input formats that hurts. I really wouldn't be complaining if strtotime claimed to do a fuzzy match. It's present behaviour is inconsistent. – anshul Dec 19 '08 at 10:20
  • @hop: That's exactly what you're saying, even more so with 'hopes high'. What hopes, if not delegating the resolution of ambiguity? And how exactly is demonstrating a bug in a function that you expect to be capable of the impossible, any kind of help to your position? – jTresidder Dec 20 '08 at 16:25
  • the "hopes" of being able to use something that promises to adhere to the mentioned GNU Date input format rules and then just not doing it. –  Dec 22 '08 at 01:36
  • The programming language is too basic to be treated seriously if it doesn't even hv a library to magically parse date – lingxiao Oct 30 '16 at 12:21
0

strtotime is the best function you could find for that. I doubt that an arbitrary string representation of a date will ever be interpreted 100% correctly, since it would require at least some information on the formatting used.

In other words: Please define natural language (You just used two different versions thereof in your question, as the php interpreter pointed out correctly)

soulmerge
  • 73,842
  • 19
  • 118
  • 155
  • Try ruby's Date.parse . No one wants perfection here. So long as the function does what it promises to. Ruby's Date.parse does the right thing in all three cases. – anshul Dec 19 '08 at 10:39
0

I'm not familiar with any, though maybe someone can offer an already-written one. In the meantime, I'd recommend running your date data through a regex or other munging before putting it through strtotime, and using a little sanity-checking on its output to see if the returned date falls in the accepted range.

J Cooper
  • 16,891
  • 12
  • 65
  • 110