strtotime с разными языками?

Работает ли strtotime только на языке по умолчанию на сервере? В приведенном ниже коде должно быть указано 11 августа 2005 г., однако в нем используется французское «aout» вместо английского «aug».

Любые идеи, как справиться с этим?

<?php
    $date = strtotime('11 aout 05');
    echo date('d M Y',$date);
?>

person Cory Dee    schedule 08.08.2011    source источник


Ответы (9)


Из документов

Разобрать любое текстовое описание даты и времени на английском языке в отметку времени Unix

Редактировать: шесть лет спустя, и то, что должно было быть побочным примечанием о том, почему strtotime() было неподходящим решением для рассматриваемой проблемы, стало принятым ответом ????

Чтобы лучше ответить на фактический вопрос, я хочу повторить ответ Марка Б.: несмотря на отрицательные голоса, date_create_from_format в сочетании с пользовательским интерпретатором месяца обеспечит наиболее надежное решение.

Однако похоже, что на данный момент все еще нет серебряной пули для синтаксического анализа международных дат, встроенного в PHP.

person Mr Griever    schedule 08.08.2011
comment
Это не отвечает на вопрос. Есть идеи, как с этим справиться? - person Giso Stallenberg; 17.10.2014
comment
Не решает вопрос - person onassar; 08.06.2015
comment
Не дает решения - person Salvi Pascual; 09.10.2015
comment
Я всегда слушаю английский.... пожалуйста, есть еще языки! любой разбор на испанский/катала? любой, как strtotime (16 марта 2016 г., Калифорния) или аналогичный? - person ; 21.03.2016
comment
В вашем ответе нет идеи. - person ; 16.09.2016

Даты французского месяца:

janvier février mars avril mai juin juillet août сентябрь октябрь ноябрь декабрь

Следовательно, для очень конкретного случая, когда месяцы на французском языке, вы можете использовать

function myStrtotime($date_string) { return strtotime(strtr(strtolower($date_string), array('janvier'=>'jan','février'=>'feb','mars'=>'march','avril'=>'apr','mai'=>'may','juin'=>'jun','juillet'=>'jul','août'=>'aug','septembre'=>'sep','octobre'=>'oct','novembre'=>'nov','décembre'=>'dec'))); }

Функция в любом случае не сломается, если вы передадите $date_string на английском языке, потому что она не будет выполнять никакой замены.

person Marco Demaio    schedule 02.05.2014

Как уже упоминалось, strtotime не учитывает локаль. Однако вы можете использовать strptime (см. http://ca1.php.net/manual/en/function.strptime.php), так как согласно документам:

Month and weekday names and other language dependent strings respect the current locale set with setlocale() (LC_TIME).

Обратите внимание, что в зависимости от вашей системы, локали и кодировки вам придется учитывать символы с диакритическими знаками.

person Technoh    schedule 03.01.2014
comment
Также обратите внимание на документы, что: Эта функция не реализована на платформах Windows, что эта функция может вести себя по-разному в разных операционных системах, и вам нужен как минимум php 5.1. - person PhoneixS; 05.05.2014
comment
Это бесполезно, потому что strptime() не принимает формат даты локали в качестве аргумента, поэтому вы не можете кодировать дату локали в другом формате с помощью strptime(). Что вы можете сделать, так это кодировать общий формат в локаль (но не наоборот). - person Alex.Default; 17.07.2018

Этот метод должен работать для вас, используя strftime:

setlocale (LC_TIME, "fr_FR.utf8"); //Setting the locale to French with UTF-8

echo strftime(" %d %h %Y",strtotime($date));

strftime

person Rashad    schedule 08.02.2015

Я написал простую функцию, частично решающую эту проблему. Он не работает как полный strtotme(), но определяет количество названий месяцев в датах.

<?php
// For example, I get the name of the month from a 
// date "1 January 2015" and set him (with different languages):

echo month_to_number('January').PHP_EOL;           // returns "01" (January)
echo month_to_number('Января', 'ru_RU').PHP_EOL;   // returns "01" (January)
echo month_to_number('Мая', 'ru_RU').PHP_EOL;      // returns "05" (May)
echo month_to_number('Gennaio', 'it_IT').PHP_EOL;  // returns "01" (January)
echo month_to_number('janvier', 'fr_FR').PHP_EOL;  // returns "01" (January)
echo month_to_number('Août', 'fr_FR').PHP_EOL;     // returns "08" (August)
echo month_to_number('Décembre', 'fr_FR').PHP_EOL; // returns "12" (December)

Аналогично можно перейти к определению чисел и дней недели и т.д.

Функция:

<?php

function month_to_number($month, $locale_set = 'ru_RU')
{
    $month  = mb_convert_case($month, MB_CASE_LOWER, 'UTF-8');
    $month  = preg_replace('/я$/', 'й', $month); // fix for 'ru_RU'
    $locale =
        setlocale(LC_TIME, '0');
        setlocale(LC_TIME, $locale_set.'.UTF-8');

    $month_number = FALSE;

    for ($i = 1; $i <= 12; $i++)
    {
        $time_month     = mktime(0, 0, 0, $i, 1, 1970);
        $short_month    = date('M', $time_month);
        $short_month_lc = strftime('%b', $time_month);

        if (stripos($month, $short_month) === 0 OR
            stripos($month, $short_month_lc) === 0)
        {
            $month_number = sprintf("%02d", $i);

            break;
        }
    }

    setlocale(LC_TIME, $locale); // return locale back

    return $month_number;
}
person DmitryS    schedule 14.10.2015

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

function getEnglishMonthName($foreignMonthName,$setlocale='nl_NL'){

  setlocale(LC_ALL, 'en_US');

  $month_numbers = range(1,12);

  foreach($month_numbers as $month)
    $english_months[] = strftime('%B',mktime(0,0,0,$month,1,2011));

  setlocale(LC_ALL, $setlocale);

  foreach($month_numbers as $month)
    $foreign_months[] = strftime('%B',mktime(0,0,0,$month,1,2011));

  return str_replace($foreign_months, $english_months, $foreignMonthName);

}

echo getEnglishMonthName('juli');
// Outputs July

Вы можете настроить это также для дней недели и для любого другого региона.

person Ogier Schelvis    schedule 05.10.2016
comment
После передачи ему полной строки даты я обнаружил, что вы можете выполнять замену имени месяца и замены имени дня в одной и той же функции. - person Ogier Schelvis; 06.10.2016

Добавление этого в качестве расширенной версии ответа Марко Демайо. Добавлены французские сокращения дней недели и месяцев:

<?php
public function frenchStrtotime($date_string) {
  $date_string = str_replace('.', '', $date_string); // to remove dots in short names of months, such as in 'janv.', 'févr.', 'avr.', ...
  return strtotime(
    strtr(
      strtolower($date_string), [
        'janvier'=>'jan',
        'février'=>'feb',
        'mars'=>'march',
        'avril'=>'apr',
        'mai'=>'may',
        'juin'=>'jun',
        'juillet'=>'jul',
        'août'=>'aug',
        'septembre'=>'sep',
        'octobre'=>'oct',
        'novembre'=>'nov',
        'décembre'=>'dec',
        'janv'=>'jan',
        'févr'=>'feb',
        'avr'=>'apr',
        'juil'=>'jul',
        'sept'=>'sep',
        'déc'=>'dec',
        'lundi' => 'monday',
        'mardi' => 'tuesday',
        'mercredi' => 'wednesday',
        'jeudi' => 'thursday',
        'vendredi' => 'friday',
        'samedi' => 'saturday',
        'dimanche' => 'sunday',
      ]
    )
  );
}
person Dmytro Sukhovoy    schedule 26.02.2018

Это зависит от локали. Если бы ему приходилось проверять каждый язык для каждого синтаксического анализа, на синтаксический анализ даже самой простой строки даты ушло бы почти НАВСЕГДА.

Если у вас есть строка с известным форматом, рассмотрите возможность использования date_create_from_format(), что будет гораздо более эффективным и меньше ошибок

person Marc B    schedule 08.08.2011
comment
Это не верно. DateTime не будет анализировать неанглийские данные. т.е. это не удастся: setlocale(LC_TIME, fr_FR); $dt = DateTime::createFromFormat('d F Y', 12 августа 2013 г.); - person Spir; 12.04.2013

Попробуйте установить локаль перед преобразованием:

setlocale(LC_TIME, "fr_FR");
person Howard    schedule 08.08.2011