Parsing localized date strings in PHP
I have some code (it's part of a wordpress plugin) which takes a text string, and the format specifier given to date(), and attempts to parse it into an array containing hour, minute, second, day, month, year.
Currently, I use the following code (note that strtotime is horribly unreliable with things like 01/02/03)
// $format contains the string originally given to date(), and $content is the rendered string
if (function_exists('date_parse_from_format')) {
$content_parsed = date_parse_from_format($format, $content);
} else {
$content = preg_replace("([0-9]st|nd|rd|th)","\\1",$content);
$content_parsed = strptime($content, dateFormatToStrftime($format));
$content_parsed['hour']=$content_parsed['tm_hour'];
$content_parsed['minute']=$content_parsed['tm_min'];
$content_parsed['day']=$content_parsed['tm开发者_如何学JAVA_mday'];
$content_parsed['month']=$content_parsed['tm_mon'] + 1;
$content_parsed['year']=$content_parsed['tm_year'] + 1900;
}
This actually works fairly well, and seems to handle every combination I've thrown at it.
However, recently someone gave me 24 Ноябрь, 2010
. This is Russian for November 24, 2010 [the date format was j F, Y
], and it is parsed as year = 2010, month = null, day = 24.
Are there any functions that I can use that know how to translate both November and Ноябрь into 11?
EDIT:
Running print_r(setlocale(LC_ALL, 0));
returns C
. Switching back to strptime()
seems to fix the problem, but the docs warn:
Internally, this function calls the strptime() function provided by the system's C library. This function can exhibit noticeably different behaviour across different operating systems. The use of date_parse_from_format(), which does not suffer from these issues, is recommended on PHP 5.3.0 and later.
Is date_parse_from_format()
the correct API, and if so, how do I get it to recognize the language?
Try to set the locale to Russian as hinted in the manual:
Month and weekday names and other language dependent strings respect the current locale set with
setlocale()
(LC_TIME
).
you could try take a locale parameter and call locale_set_default($locale) before doing the date parsing.
$originalLocale = locale_get_default();
$locale ? $locale : $originalLocale;
locale_set_default(locale);
// date parsing code
locale_set_default($originalLocale);
I haven't testing this but it's work a try. FYI, I believe the locale string for Russian is "ru-Latn"
I see that the question is already answered but none of the solutions provided worked for me.
This is my solution:
if(!preg_match('/^en_US/', $locale)){
$months_short = array('jan' => t('jan'), 'feb' => t('feb'), 'mar' => t('mar'), 'apr' => t('apr'),
'may' => t('may'), 'jun' => t('giu'), 'jul' => t('lug'), 'aug' => t('ago'),
'sep' => t('set'), 'oct' => t('ott'), 'nov' => t('nov'), 'dec' => t('dec'));
foreach ($months_short as $month_short => $month_short_translated) {
$date = preg_replace('/'.$month_short_translated.'/', $month_short, strtolower($date));
}
}
$pieces = date_parse_from_format($format,$date);
if($pieces && $pieces['error_count'] == 0 && checkdate($pieces['month'], $pieces['day'], $pieces['year'])){
return date('Y-m-d', mktime(0,0,0,$pieces['month'],$pieces['day'],$pieces['year']));
}
Where t() returns the translated abbreviation for the month.
Probably not the best solution ever (because it fails if there is no valid translation) but it works for my case.
精彩评论