Skip to content

Commit

Permalink
Add the ability to override ICU values for week numbering - useful wh…
Browse files Browse the repository at this point in the history
…en the ICU library can't be updated.
  • Loading branch information
campbell-m committed Nov 8, 2023
1 parent 38bf057 commit 5d85299
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 5 deletions.
29 changes: 28 additions & 1 deletion web/language.inc
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,13 @@ function get_loc_field_name(string $table, string $name) : string

function datetime_format(array $format, int $timestamp=null, string $locale=null) : string
{
global $icu_override, $timezone;

if (!isset($timestamp))
{
$timestamp = time();
}

if (!isset($locale))
{
$locale = get_mrbs_locale();
Expand All @@ -809,7 +816,27 @@ function datetime_format(array $format, int $timestamp=null, string $locale=null
null, null, $pattern
);

return $formatter->format($timestamp ?? time());
// If we're overriding the ICU value(s) then use those, provided that we're able to make use
// of them with the IntlCalendar and (standard, not emulated - hence the check for the loaded
// extension, rather than whether the class exists, which it always will) IntlDateFormatter classes.
if (isset($icu_override[$locale]) && extension_loaded('intl') && class_exists('IntlCalendar'))
{
$cal = \IntlCalendar::createInstance($timezone, $locale);
{
if (isset($icu_override[$locale]['first_day_of_week']))
{
$cal->setFirstDayOfWeek($icu_override[$locale]['first_day_of_week']);
}
if (isset($icu_override[$locale]['minimal_days_in_first_week']))
{
$cal->setMinimalDaysInFirstWeek($icu_override[$locale]['minimal_days_in_first_week']);
}
}
$cal->setTime($timestamp * 1000);
return $formatter->format($cal);
}

return $formatter->format($timestamp);
}


Expand Down
31 changes: 27 additions & 4 deletions web/lib/MRBS/DateTime.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public static function createFromFormat($format, $datetime, ?\DateTimeZone $time
// the method assumes that the week starts on a Monday.
public static function firstDayOfWeek(?string $timezone = null, ?string $locale = null) : int
{
global $icu_override;

$default = 1; // Monday

if (!class_exists('\\IntlCalendar'))
Expand All @@ -56,11 +58,32 @@ public static function firstDayOfWeek(?string $timezone = null, ?string $locale
return $default;
}

$first_day = $calendar->getFirstDayOfWeek();
if ($first_day === false)
// If we're overriding the ICU library then use that value
if (isset($icu_override[$locale]['first_day_of_week']))
{
trigger_error($calendar->getErrorMessage(), E_USER_WARNING);
return $default;
$first_day = $icu_override[$locale]['first_day_of_week'];
// Check that it's a valid day
if (!in_array($first_day, array(
IntlCalendar::DOW_SUNDAY,
IntlCalendar::DOW_MONDAY,
IntlCalendar::DOW_TUESDAY,
IntlCalendar::DOW_WEDNESDAY,
IntlCalendar::DOW_THURSDAY,
IntlCalendar::DOW_FRIDAY,
IntlCalendar::DOW_SATURDAY
)))
{
throw new Exception('$icu_override[' . $locale . "]['first_day_of_week'] must be in the range [1..7]");
}
}
// Otherwise just get the standard value from ICU
else
{
$first_day = $calendar->getFirstDayOfWeek();
if ($first_day === false) {
trigger_error($calendar->getErrorMessage(), E_USER_WARNING);
return $default;
}
}

return $first_day - 1; // IntlCalendar::DOW_SUNDAY = 1, so we need to subtract 1
Expand Down
20 changes: 20 additions & 0 deletions web/systemdefaults.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,26 @@
);


/***************
* ICU overrides
* *************/

// Sometimes we may want to override the standard ICU library settings,
// for example if the ICU library on the server is out of date and can't
// be updated. This can be done by setting:
//
// $icu_override[<locale>]['first_day_of_week'] and/or
// $icu_override[<locale>]['minimal_days_in_first_week']
//
// where <locale> is a valid locale in BCP 47 format and both settings take
// integer values in the range 1..7 (IntlCalendar days start with Sunday = 1).

// For example:
//
// $icu_override['en-AU']['first_day_of_week'] = 2; // Monday
// $icu_override['en-AU']['minimal_days_in_first_week'] = 1;


/************************
* Miscellaneous settings
************************/
Expand Down

0 comments on commit 5d85299

Please sign in to comment.