Локализованные (короткие) месячные имена с использованием IntlDateFormatter в PHP?

На моей машине разработки Windows я установил локаль в ita :

 setlocale(LC_TIME, 'ita'); echo strftime('%b'); // dic 

Хотя (я полагаю, не могу проверить прямо сейчас) в системе * nix, я должен использовать it :

 setlocale(LC_TIME, 'it'); 

Если я попытаюсь установить it на моем Windows, это не сработает, печать Dec

Кажется, я не могу полагаться на setlocale() , поэтому я должен использовать IntlDateFormatter как было предложено @hakre. Тем не менее, я могу найти константу, которая дает мне название месяца и короткое:

 IntlDateFormatter::NONE (integer) Do not include this element IntlDateFormatter::FULL (integer) Completely specified style (Tuesday, April 12, 1952 AD or 3:30:42pm PST) IntlDateFormatter::LONG (integer) Long style (January 12, 1952 or 3:30:32pm) IntlDateFormatter::MEDIUM (integer) Medium style (Jan 12, 1952) IntlDateFormatter::SHORT (integer) Most abbreviated style, only essential data (12/13/52 or 3:30pm) 

Из справки , некоторые месячные коды форматирования:

 Symbol Meaning Example: M month in year M or MM 09 MMM Sept MMMM September MMMMM S 

Функция PHP для установки формата: IntlDateFormatter::setPattern , некоторые примеры:

 class LocaleDateFormat { private $locale; private $pattern; public function __construct($pattern, $locale = 'en_US') { $this->setLocale($locale); $this->setPattern($pattern); } public function setLocale($locale) { $this->locale = $locale; } public function setPattern($pattern) { $this->pattern = $pattern; } public function localeFormat($locale, $date) { $this->setLocale($locale); return $this->format($date); } public function format($date) { $formatter = new IntlDateFormatter($this->locale, IntlDateFormatter::FULL, IntlDateFormatter::FULL); $formatter->setPattern($this->pattern); return $formatter->format($date); } } $dateFormat = new LocaleDateFormat('MMMM'); # Long Month Names $date = new DateTime(); # Now $locales = ["en_US", "de_DE", "sv_SE", "ru_RU"]; foreach ($locales as $i => $locale) { $month = $dateFormat->localeFormat($locale, $date); printf("%d. %s - %s\n", $i+1, $locale, $month); } 

Вывод:

 1. en_US - December 2. de_DE - Dezember 3. sv_SE - december 4. ru_RU - декабря 

Список локалей см. Здесь:

  • Список доступных коллакторов в PHP?

Фактический пример коротких имен в разных местах:

 $locales = ["en_US", "de_DE", "sv_SE", "ru_RU", 'it', 'it_IT', 'it_CH']; $dateFormat = new LocaleDateFormat('MMM'); # Short Month Names $date = new DateTime(); # Now foreach (range(1, 12) as $monthNumber) { $date->setDate(2012, $monthNumber, 1); printf("%02d: ", $monthNumber); foreach ($locales as $locale) { $monthLabel = $dateFormat->localeFormat($locale, $date); $pad = str_repeat(' ', max(0, 8 - mb_strlen($monthLabel, 'UTF-8'))); printf("%s: %s%s ", $locale, $monthLabel, $pad); } echo "\n"; } 

Примерный вывод:

 01: en_US: Jan de_DE: Jan sv_SE: jan ru_RU: янв. it: gen it_IT: gen it_CH: gen 02: en_US: Feb de_DE: Feb sv_SE: feb ru_RU: февр. it: feb it_IT: feb it_CH: feb 03: en_US: Mar de_DE: Mär sv_SE: mar ru_RU: марта it: mar it_IT: mar it_CH: mar 04: en_US: Apr de_DE: Apr sv_SE: apr ru_RU: апр. it: apr it_IT: apr it_CH: apr 05: en_US: May de_DE: Mai sv_SE: maj ru_RU: мая it: mag it_IT: mag it_CH: mag 06: en_US: Jun de_DE: Jun sv_SE: jun ru_RU: июня it: giu it_IT: giu it_CH: giu 07: en_US: Jul de_DE: Jul sv_SE: jul ru_RU: июля it: lug it_IT: lug it_CH: lug 08: en_US: Aug de_DE: Aug sv_SE: aug ru_RU: авг. it: ago it_IT: ago it_CH: ago 09: en_US: Sep de_DE: Sep sv_SE: sep ru_RU: сент. it: set it_IT: set it_CH: set 10: en_US: Oct de_DE: Okt sv_SE: okt ru_RU: окт. it: ott it_IT: ott it_CH: ott 11: en_US: Nov de_DE: Nov sv_SE: nov ru_RU: нояб. it: nov it_IT: nov it_CH: nov 12: en_US: Dec de_DE: Dez sv_SE: dec ru_RU: дек. it: dic it_IT: dic it_CH: dic 

Довольно уродливый, но он работает:

 $formatter = \IntlDateFormatter::create( 'it', \IntlDateFormatter::LONG, \IntlDateFormatter::NONE, \DateTimeZone::UTC, // Doesn't matter \IntlDateFormatter::GREGORIAN, 'MMM' ); $months = array_map( function($m) use($formatter){ return $formatter->format(mktime(0, 0, 0, $m, 2, 1970)); }, range(1, 12) ); var_dump($months); 

Странно, что с it месячные имена являются строчными, а у них есть правильный случай. Я оставлю вопрос без ответа в поисках лучшего решения!