开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜