PHP date - get name of the months in local language
Asked Answered
V

6

33

I have this part of the function, which gives me name of the months in English. How can I translate them to my local language (Serbian)?

$month_name = date('F', mktime(0, 0, 0, $i));

Where $i is the number of the month (values 1 - 12). See also PHP:mktime.

Verbatim answered 12/12, 2012 at 17:44 Comment(1)
strftime, and install the proper locale, & set your current locale to serbian.Sonnier
T
27

You should use setlocale():

setlocale(LC_TIME, 'fr_FR');
$month_name = date('F', mktime(0, 0, 0, $i));

In this case it would set it to French. For your case it should be one of the following:

  1. sr_BA - Serbian (Montenegro)
  2. sr_CS - Serbian (Serbia)
  3. sr_ME - Serbian (Serbia and Montenegro)
Trichromatism answered 12/12, 2012 at 17:46 Comment(3)
My date is locale unaware, my strftime is not. If yours is locale aware... what's your PHP version?Sonnier
But notice that setlocale sets the locale process wide (causing unexpected behavior with multiple threads when using multi-threading). Thread safe alternative: IntlDateFormatterAssessor
This solution is incorrect. Let's say it's 2019-01-30, the function mktime() without the fifth and sixth parameter will use the current day and year, so if it's 2019-01-30 and you want to know $i = 2 (February), the result will be March, because 2019-02-30 doesn't exist and it will be interpreted as a date in March. To avoid this problem, use for example: mktime(0, 0, 0, $i, 1, 2019). Anyway, don't use this solution, because it will give the wrong result on certain specific dates. So many incorrect answers on Stackoverflow ...Speedball
C
23

You should use setlocale() and strftime():

setlocale(LC_TIME, 'sr_CS');
$month_name = strftime('%B', mktime(0, 0, 0, $i));
Cinematograph answered 11/1, 2016 at 8:0 Comment(3)
it has issues with time zone on datetime object if you use setTimezone() and use getTimestamp()Tigges
this work for me, sadly on my machine setLocale() not affect date()Veratrine
strftime() deprecated in PHP 8.lHives
R
18

Here is an example with IntlDateFormatter

$format = new IntlDateFormatter('sr_CS', IntlDateFormatter::NONE, 
              IntlDateFormatter::NONE, NULL, NULL, "MMM");
$monthName = datefmt_format($format, mktime(0, 0, 0, $i));
Rubenstein answered 14/6, 2017 at 9:4 Comment(1)
Hello, here please change locale to "en" and month number to 11. Then it shows me dec and not Nov. Can you please guide?Synge
H
13

For all who struggle with German (and de_DE), make sure you are using the right language code. Login to your server and run locale -a to see a list of all available ones. For me it shows:

C
C.UTF-8
de_AT.utf8
de_BE.utf8
de_CH.utf8
de_DE.utf8
de_LI.utf8
de_LU.utf8
...

You need to use one of those codes.

Then you can use:

date_default_timezone_set('Europe/Berlin');
setlocale(LC_ALL, 'de_DE.utf8');
$date_now = date('Y-m-d');
$month_available = strftime('%B %Y', strtotime($date_now));
$month_next = strftime('%B %Y', strtotime($date_now.' +1 month'));

and "März 2020" etc. get displayed correctly.

Haveman answered 14/2, 2020 at 12:20 Comment(0)
B
6

This question asks how to get a list of months, I only see hints, not a complete code answer so:

If you have IntlDateFormatter available - which is available in most of the cases, you can create a formatter in a given locale and repeatedly push a date to it created just based on month number

// or any other locales like pl_PL, cs_CZ, fr_FR, zh, zh_Hans, ...
$locale = 'en_GB';
$dateFormatter = new IntlDateFormatter(
    $locale,
    IntlDateFormatter::LONG, // date type
    IntlDateFormatter::NONE  // time type
);
$dateFormatter->setPattern('LLLL'); // full month name with NO DECLENSION ;-)
$months_locale = [];
for ($month_number = 1; $month_number <= 12; ++$month_number) {
    $months_locale[] = $dateFormatter->format(
        // 'n' => month number with no leading zeros
        DateTime::createFromFormat('n', (string)$month_number)
    );
}
// test output
echo "<pre>";
var_dump($months_locale);
echo "</pre>";

Note: LLLL takes care of not-declining, but it does not take care of the lowercase/uppercase of the first letter if the languages has such things.
Good example is that you can get January for en_GB but leden for cs_CZ
If you want all letters lowercase => use mb_strtolower($month_name); - docs
If you want just the FIRST letter to be upper case =>
=> use mb_convert_case($month_name, MB_CASE_TITLE, 'UTF-8'); - docs

Always use mb_* functions or their variations for locale-originating strings !

So no, don't use ucfirst !

Berm answered 25/2, 2021 at 23:54 Comment(0)
I
1

It is good idea to pass the encoding when setting the locale:

 <?php    
 date_default_timezone_set('Europe/Belgrade');
 setlocale(LC_TIME, array('sr_CS.UTF-8', 'sr.UTF-8'));
Intro answered 3/1, 2018 at 13:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.