27

Does strtotime only work in the default language on the server? The below code should resolve to august 11, 2005, however it uses the french "aout" instead of the english "aug".

Any ideas how to handle this?

<?php
    $date = strtotime('11 aout 05');
    echo date('d M Y',$date);
?>
Cory Dee
  • 2,858
  • 6
  • 40
  • 55

9 Answers9

11

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.

Technoh
  • 1,606
  • 15
  • 34
  • Also note from docs that: _This function is not implemented on Windows platforms_, that this function can have different behaviour across different operating systems and you need at least php 5.1. – PhoneixS May 05 '14 at 07:25
  • It's kinda useless due to `strptime()` doesn't accept locale date format as argument, so you can't encode locale date in another format with `strptime()`. What you **can do** is encode common format into locale (but not vice versa) – Alex.Default Jul 17 '18 at 07:49
11

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.

Marco Demaio
  • 33,578
  • 33
  • 128
  • 159
10

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

Rashad
  • 1,344
  • 2
  • 17
  • 33
10

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.

Mr Griever
  • 4,014
  • 3
  • 23
  • 41
5

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'){
  
  $originalLocale = Locale::getDefault();
  
  setlocale(LC_ALL, 'en_US');

  $monthNumbers = range(1,12);
  
  foreach($monthNumbers as $month)
    $englishMonths[] = strftime('%B',mktime(0,0,0,$month,1,2011));
  
  setlocale(LC_ALL, $setLocale);
 
  foreach($monthNumbers as $month)
    $foreignMonths[] = strftime('%B',mktime(0,0,0,$month,1,2011));

  return str_replace($foreignMonths, $englishMonths, $foreignMonthName);

  setlocale(LC_ALL, $originalLocale)
  
}

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

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

Ogier Schelvis
  • 602
  • 12
  • 22
  • After passing a full date string to it I found out you can do month name replacement and day name replacement in the same function. – Ogier Schelvis Oct 06 '16 at 07:59
4

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;
}
DmitryS
  • 261
  • 2
  • 3
0

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',
      ]
    )
  );
}
Anto Jose
  • 35
  • 1
  • 7
Dmytro Sukhovoy
  • 952
  • 5
  • 17
-2

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

Marc B
  • 356,200
  • 43
  • 426
  • 500
  • 1
    This is wrong. DateTime won't parse non-english data. ie this will fail: setlocale(LC_TIME, "fr_FR"); $dt = DateTime::createFromFormat('d F Y', "12 Août 2013"); – Spir Apr 12 '13 at 12:12
-3

Try to set the locale before conversion:

setlocale(LC_TIME, "fr_FR");
Howard
  • 38,639
  • 9
  • 64
  • 83