strtotime With Different Languages?

夙愿已清 提交于 2019-11-26 17:55:18

From the docs

Parse about any English textual datetime description into a Unix timestamp

Edit: Six years down the road now, and what was meant to be a side-note about why strtotime() was an inappropriate solution for the issue at hand became the accepted answer 😲

To better answer the actual question I want to echo Marc B's answer: despite the downvotes, date_create_from_format, paired with a custom Month interpreter will provide the most reliable solution

However it appears that there is still no silver-bullet for international date parsing built-in to PHP for the time being.

As mentioned strtotime does not take locale into account. However you could use strptime (see http://ca1.php.net/manual/en/function.strptime.php), since according to the docs:

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

Note that depending on your system, locale and encoding you will have to account for accented characters.

French month dates are:

janvier février mars avril mai juin juillet août septembre octobre novembre décembre

Hence, for the very specific case where months are in French you could use

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'))); }

The function anyway does not break if you pass $date_string in English, because it won't do any substitution.

This method should work for you using strftime:

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

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

strftime

I wrote a simple function partially solves this problem. It does not work as a full strtotme(), but it determines the number of months names in the dates.

<?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)

Similarly, we can proceed to determine the numbers and days of the week, etc.

Function:

<?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;
}

The key to solving this question is to convert foreign textual representations to their English counterparts. I also needed this, so inspired by the answers already given I wrote a nice and clean function which would work for retrieving the English month name.

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

You can adjust this for days of the week aswell and for any other locale.

Dmytro Sukhovoy

Adding this as an extended version of Marco Demaio answer. Added french days of the week and months abbreviations:

<?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',
      ]
    )
  );
}

It's locale dependent. If it had to check every language for every parse, it'd take nigh-on FOREVER to parse even the simplest of date strings.

If you've got a string with known format, consider using date_create_from_format(), which'll be far more efficient and less error-print

Try to set the locale before conversion:

setlocale(LC_TIME, "fr_FR");
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!