MDL-83412 core: Use LLL/LLLL for standalone Month names
We currently use MMM and MMMM which mean 'month in year', however in some locales this is context-specific and should only be used in conjunction with a day, for example "10 October 2024". LLL and LLLL are for "stand-alone on the in year" and should be used when a month is used without a day.
This commit is contained in:
+19
-5
@@ -741,13 +741,14 @@ class core_date {
|
||||
$intl_formats = [
|
||||
'%a' => 'EEE', // An abbreviated textual representation of the day Sun through Sat
|
||||
'%A' => 'EEEE', // A full textual representation of the day Sunday through Saturday
|
||||
'%b' => 'MMM', // Abbreviated month name, based on the locale Jan through Dec
|
||||
'%B' => 'MMMM', // Full month name, based on the locale January through December
|
||||
'%h' => 'MMM', // Abbreviated month name, based on the locale (an alias of %b) Jan through Dec
|
||||
];
|
||||
|
||||
$intl_formatter = function (DateTimeInterface $timestamp, string $format) use ($intl_formats, $locale) {
|
||||
|
||||
$originalformat = $format;
|
||||
$intl_formatter = function (DateTimeInterface $timestamp, string $format) use (
|
||||
$intl_formats,
|
||||
$locale,
|
||||
$originalformat,
|
||||
) {
|
||||
// Map IANA timezone DB names (used by PHP) to those used internally by the "intl" extension. The extension uses its
|
||||
// own data based on ICU timezones, which may not necessarily be in-sync with IANA depending on the version installed
|
||||
// on the local system. See: https://unicode-org.github.io/icu/userguide/datetime/timezone/#updating-the-time-zone-data
|
||||
@@ -789,6 +790,19 @@ class core_date {
|
||||
$time_type = IntlDateFormatter::MEDIUM;
|
||||
break;
|
||||
|
||||
case "%B":
|
||||
case "%b":
|
||||
case "%h":
|
||||
// Check for any day (%d, or %e) in the string.
|
||||
if (preg_match('/%[de]/', $originalformat)) {
|
||||
// The day is present so use the standard format.
|
||||
$pattern = $format === '%B' ? 'MMMM' : 'MMM';
|
||||
} else {
|
||||
// The day is not present so use the stand-alone format.
|
||||
$pattern = $format === '%B' ? 'LLLL' : 'LLL';
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$pattern = $intl_formats[$format];
|
||||
}
|
||||
|
||||
@@ -627,6 +627,36 @@ class date_test extends advanced_testcase {
|
||||
"%c",
|
||||
"20 February 2024 at 1:09 pm",
|
||||
],
|
||||
'Month Year only' => [
|
||||
"1708405742",
|
||||
"%B %Y",
|
||||
"February 2024",
|
||||
],
|
||||
'Abbreviated Month Year only' => [
|
||||
"1708405742",
|
||||
"%b %Y",
|
||||
"Feb 2024",
|
||||
],
|
||||
'DD Month Year' => [
|
||||
"1708405742",
|
||||
"%d %B %Y",
|
||||
"20 February 2024",
|
||||
],
|
||||
'D Month Year' => [
|
||||
"1708405742",
|
||||
"%e %B %Y",
|
||||
"20 February 2024",
|
||||
],
|
||||
'Abbreviated DD Month Year' => [
|
||||
"1708405742",
|
||||
"%d %b %Y",
|
||||
"20 Feb 2024",
|
||||
],
|
||||
'Abbreviated D Month Year' => [
|
||||
"1708405742",
|
||||
"%e %b %Y",
|
||||
"20 Feb 2024",
|
||||
],
|
||||
'numeric_c' => [
|
||||
1708405742,
|
||||
"%c",
|
||||
@@ -666,4 +696,65 @@ class date_test extends advanced_testcase {
|
||||
public function test_strftime(mixed $input, string $format, string $expected): void {
|
||||
$this->assertEqualsIgnoringWhitespace($expected, core_date::strftime($format, $input));
|
||||
}
|
||||
|
||||
public static function get_strftime_locale_provider(): array {
|
||||
return [
|
||||
'Month Year only' => [
|
||||
"1728487000",
|
||||
'ru_RU.UTF-8',
|
||||
"%B %Y",
|
||||
"октябрь 2024",
|
||||
],
|
||||
'DD Month Year' => [
|
||||
"1728487000",
|
||||
'ru_RU.UTF-8',
|
||||
"%d %B %Y",
|
||||
"09 октября 2024",
|
||||
],
|
||||
'D Month Year' => [
|
||||
"1728487000",
|
||||
'ru_RU.UTF-8',
|
||||
"%e %B %Y",
|
||||
" 9 октября 2024",
|
||||
],
|
||||
'Abbreviated Month Year only' => [
|
||||
"1728487000",
|
||||
'ru_RU.UTF-8',
|
||||
"%b %Y",
|
||||
"окт. 2024",
|
||||
],
|
||||
'Abbreviated DD Month Year' => [
|
||||
"1728487000",
|
||||
'ru_RU.UTF-8',
|
||||
"%d %b %Y",
|
||||
"09 окт. 2024",
|
||||
],
|
||||
'Abbreviated D Month Year' => [
|
||||
"1728487000",
|
||||
'ru_RU.UTF-8',
|
||||
"%e %b %Y",
|
||||
" 9 окт. 2024",
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test \core_date::strftime function with alternate languages.
|
||||
*
|
||||
* @dataProvider get_strftime_locale_provider
|
||||
* @param mixed $input Input passed to strftime
|
||||
* @param string $locale The locale
|
||||
* @param string $format The date format to pass to strftime, falls back to '%c' if null
|
||||
* @param string $expected The output generated by strftime
|
||||
*/
|
||||
public function test_strftime_locale(
|
||||
mixed $input,
|
||||
string $locale,
|
||||
string $format,
|
||||
string $expected,
|
||||
): void {
|
||||
$this->assertEqualsIgnoringWhitespace(
|
||||
$expected,
|
||||
core_date::strftime($format, $input, $locale));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user