Разбор локализованных строк даты в PHP

У меня есть код (он является частью плагина wordpress), который принимает текстовую строку и спецификатор формата, заданный date (), и пытается проанализировать его в массиве, содержащем час, минуту, секунду, день, месяц, год.

В настоящее время я использую следующий код (обратите внимание, что strtotime ужасно ненадежна с такими вещами, как 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_mday']; $content_parsed['month']=$content_parsed['tm_mon'] + 1; $content_parsed['year']=$content_parsed['tm_year'] + 1900; } 

Это действительно работает достаточно хорошо и, похоже, обрабатывает каждую комбинацию, которую я выбрал.

Однако недавно кто-то дал мне 24 Ноябрь, 2010 . Это русская версия для 24 ноября 2010 года [формат даты был j F, Y ], и он анализируется как year = 2010, month = null, day = 24.

Существуют ли какие-либо функции, которые я могу использовать, которые знают, как перевести ноябрь и ноябрь в 11?

РЕДАКТИРОВАТЬ:

Запуск print_r(setlocale(LC_ALL, 0)); возвращает C Переключение обратно в strptime() кажется, strptime() проблему, но документы предупреждают:

Внутри эта функция вызывает функцию strptime (), предоставляемую библиотекой C системы. Эта функция может демонстрировать заметно различное поведение в разных операционных системах. Использование date_parse_from_format (), которое не страдает от этих проблем, рекомендуется на PHP 5.3.0 и более поздних версиях.

Является ли date_parse_from_format() правильным API, и если да, то как мне его распознать?

Попробуйте установить языковой стандарт на русский, как указано в руководстве :

Имена месяца и дня недели и другие зависящие от языка строки соответствуют текущему языку, установленному с помощью setlocale() (LC_TIME ).

вы можете попробовать взять параметр локали и вызвать locale_set_default ($ locale), прежде чем выполнять синтаксический анализ даты.

 $originalLocale = locale_get_default(); $locale ? $locale : $originalLocale; locale_set_default(locale); // date parsing code locale_set_default($originalLocale); 

Я не тестировал это, но это попытка попробовать. FYI, я считаю, что языковая строка для русского языка – «ru-Latn»

Я вижу, что на этот вопрос уже дан ответ, но ни одно из предоставленных решений не сработало для меня.

Это мое решение:

 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('Ym-d', mktime(0,0,0,$pieces['month'],$pieces['day'],$pieces['year'])); } 

Где t () возвращает переведенную аббревиатуру для месяца.

Наверное, это не лучшее решение когда-либо (потому что оно терпит неудачу, если нет действительного перевода), но он работает для моего дела.