I can't beleive I've never come across this one before.
Basically, I'm parsing the text in human-created text documents and one of the fields I need to parse is a date and time. Because I'm in Australia, dates are formatted like dd/mm/yyyy
but strtotime
only wants to parse it as a US formatted date. Also, exploding by /
isn't going to work because, as I mentioned, these documents are hand-typed and some of them take the form of d M yy
.
I've tried multiple combinations of setlocale
but no matter what I try, the language is always set to US English.
I'm fairly sure setlocale is the key here, but I don't seem to be able to strike upon the right code. Tried these:
Anything else I can try?
For clarity: I'm running on IIS with a Windows box.
Thanks so much :)
Iain
Example:
$mydatetime = strtotime("9/02/10 2.00PM");
echo date('j F Y H:i', $mydatetime);
Produces
2 September 2010 14:00
I want it to produce:
9 February 2010 14:00
My solution
I'm giving the tick to one of the answers here as it is a much easier-to-read solution to mine, but here's what I've come up with:
$DateTime = "9/02/10 2.00PM";
$USDateTime = preg_replace('%([0-3]?[0-9]{1})\s*?[\./ ]\s*?((?:1[0-2])|0?[0-9])\s*?[./ ]\s*?(\d{4}|\d{2})%', '${2}/${1}/${3}', $DateTime);
echo date('j F Y H:i',strtotime($USDateTime));
Because I can't rely on users to be consistent with their date entry, I've made my regex a bit more complex:
Hopefully this will match most styles of date writing...
There's a quick fix that seems to force PHP's strtotime
into using the UK date format.
That is: to replace all of the '/' in the incoming string with a '-'.
Example:
date('Y-m-d', strtotime('01/04/2011'));
Would produce: 2011-01-04
date('Y-m-d', strtotime('01-04-2011'));
Would produce: 2011-04-01
You could use str_replace
to achieve this.
Example:
str_replace('/', '-', '01/04/2011');
EDIT:
As stated in the comments, this works because PHP interprets slashes as American and dots/dashes as European.
I've used this trick extensively and had no problems so far.
If anyone has any good reasons not to use this, please comment.
The problem is that strtotime
doesn't take a format argument. What about strptime
?
setlocale() sucks for exactly the reason you describe: You never know what you're going to get. Best to process the string manually.
Zend Framework's Zend_Date is one alternative promising more exact and consistent date handling. I don't have experience with it myself yet, just beginning to work with it, but so far, I like it.
Ah, the old problem us lucky Australians get.
What I've done in the past is something like this
public static function getTime($str) { // 3/12/2008
preg_match_all('/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/', $str, $matches);
return (isset($matches[0][0])) ? strtotime($matches[3][0] . '-' . $matches[2][0] . '-' . $matches[1][0]) : NULL;
}
Though this relies on dates in this format dd/mm/yyyy
.
You can probably use another regex or so to convert from d M yy
or use a modified one. I don't know if this would be correct but it may be a start:
/^(\d{1,2})(?:\/|\s)(\d{1,2})(?:\/|\s)(\d{2,4})$/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With