У меня есть код (он является частью плагина 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 () возвращает переведенную аббревиатуру для месяца.
Наверное, это не лучшее решение когда-либо (потому что оно терпит неудачу, если нет действительного перевода), но он работает для моего дела.