如何使用 IntlDateFormatter 格式化日期,使用 MEDIUM 或 FULL 日期类型,但没有年份


How to format date with a IntlDateFormatter using MEDIUM or FULL datetype, but without a year?

首先:我知道我可以为每个语言环境手动创建一堆具有相应模式的配置文件;实际上,我尝试仅使用IntlDateFormatter找到解决方法。

我将尝试用示例来解释。

<?php
$tz = new DateTimeZone('Europe/Moscow');
$now = time();
foreach (['en_US', 'ja_JA', 'ru_RU'] as $locale) {
    printf("%s:'n", $locale);
    foreach ([IntlDateFormatter::MEDIUM, IntlDateFormatter::LONG] as $datetype) {
        $formatter = new IntlDateFormatter($locale, $datetype, IntlDateFormatter::NONE);
        printf("- %s'n", $formatter->format($now));
    }
}

https://3v4l.org/iJOT4

这会产生

en_US:
- Feb 1, 2016
- February 1, 2016
ja_JA:
- 2016/02/01
- 2016年2月1日
ru_RU:
- 1 февр. 2016 г.
- 1 февраля 2016 г.

我需要

en_US:
- Feb 1
- February 1
ja_JA:
- 02/01
- 2月1日
ru_RU:
- 1 февр.
- 1 февраля

第一个想法是为给定的区域设置提取模式并删除任何"y"和"Y"字母。但正如你所看到的,不仅仅是一个4位数的年份:所有的逗号,斜杠,标签(如"г."和"年"(。

附注:

实际上,我想要从理想的IntlDateFormatter实现中获得的是一个智能模式,其中所有组件都在它们的位置,但我可以配置每个组件使用的模式。比如:ru_RU格式化程序没有'd MMMM y г.'模式,而是具有'dmy'模式,而对于d组件,它具有d模式,m - MMMMy - y г. 。所以我可以说y组件是一个"(空字符串(,瞧。

另外,如果您知道任何已经这样做的库 - 请告诉我。

所以,目前这是不可能的。我发现intl PHP 扩展只是缺少DateTimePatternGenerator(http://userguide.icu-project.org/formatparse/datetime(,这正是我所需要的。

类提供了一种将对一组日期/时间字段的请求及其宽度映射到适合区域设置的格式模式的方法。该请求采用"骨架"的形式,该框架仅包含使用所需宽度表示的所需字段的模式字母。在骨架中,除了模式字母之外的任何内容都会被忽略,字段顺序无关紧要,并且可以使用两个特殊的附加模式字母:"j"请求区域设置的首选小时周期类型(它映射到"H"、"h"、"k"或"K"之一(;"J"类似,但即使区域设置的首选小时周期类型为"h"或"K",也不会请求 AM/PM 标记。

例如,"MMMMdjmm"的框架可能会导致不同区域设置的以下格式模式:

区域设置 |骨架"MMMMdjmm"的格式模式 |例~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~en_US "MMMM d 'at' h:mm a" 4月2日下午5:00es_ES "d 'de' MMMM, H:mm" 2 de abril, 17:00ja_JP "M月d日 H:mm" 4月2日 17:00

另外,我发现 HHVM 已经实现了它 — https://github.com/facebook/hhvm/commit/bc84daf7816e4cd268da59d535dcadfc6cf01085 .我希望有一天这会被移植到PHP。

UPD:我写了一篇关于这个问题的长篇文章——https://blog.ksimka.com/a-long-journey-to-formatting-a-date-without-a-year-internationally-with-php/