Skip to content

Commit

Permalink
Use the IntlCalendar extension if possible to find the first day of t…
Browse files Browse the repository at this point in the history
…he week in the user's locale. The week numbers in MRBS are based on the week number in the locale, which won't necessarily be the ISO week number.
  • Loading branch information
campbell-m committed Nov 1, 2023
1 parent d944be8 commit 1af44b8
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 16 deletions.
5 changes: 3 additions & 2 deletions web/functions_table.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1586,6 +1586,7 @@ function month_room_table_innerhtml(string $view, int $view_all, int $year, int
global $weekstarts, $view_week_number, $show_plus_link, $monthly_view_entries_details;
global $enable_periods, $morningstarts, $morningstarts_minutes;
global $prevent_booking_on_holidays, $prevent_booking_on_weekends;
global $timezone;

// Check that we've got a valid, enabled room
if (is_null(get_room_name($room)) || !is_visible($room))
Expand Down Expand Up @@ -1668,8 +1669,8 @@ function month_room_table_innerhtml(string $view, int $view_all, int $year, int
'area' => $area,
'room' => $room);

// If it's a Monday (the start of the ISO week), show the week number
if ($view_week_number && (($weekcol + $weekstarts)%DAYS_PER_WEEK == 1))
// If it's the first day of the week, show the week number
if ($view_week_number && (($weekcol + $weekstarts)%DAYS_PER_WEEK == DateTime::firstDayOfWeek($timezone, get_mrbs_locale())))
{
$vars['view'] = 'week';
$query = http_build_query($vars, '', '&');
Expand Down
8 changes: 4 additions & 4 deletions web/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ function get_calendar_nav(string $view, int $view_all, int $year, int $month, in

function get_date_heading(string $view, int $year, int $month, int $day) : string
{
global $datetime_formats, $display_timezone,
global $datetime_formats, $display_timezone, $timezone,
$weekstarts, $view_week_number;

$html = '';
Expand All @@ -344,9 +344,9 @@ function get_date_heading(string $view, int $year, int $month, int $day) : strin
break;

case 'week':
// Display the week number if required, provided the week starts on Monday,
// otherwise it's spanning two ISO weeks and doesn't make sense.
if ($view_week_number && ($weekstarts == 1))
// Display the week number if required, provided the MRBS week starts on the first day
// of the week, otherwise it's spanning two weeks and doesn't make sense.
if ($view_week_number && ($weekstarts == DateTime::firstDayOfWeek($timezone, get_mrbs_locale())))
{
$html .= '<span class="week_number">' .
get_vocab('week_number', datetime_format($datetime_formats['week_number'], $time)) .
Expand Down
4 changes: 2 additions & 2 deletions web/js/datepicker.js.php
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,8 @@ function (date) {
}
else
{
<?php // Only display the week number if the week starts on a Monday (the start of the ISO week ?>
config.weekNumbers = <?php echo ($mincals_week_numbers && ($weekstarts == 1)) ? 'true' : 'false' ?>;
<?php // Only display the week number if the MRBS week starts on the first day of the week ?>
config.weekNumbers = <?php echo ($mincals_week_numbers && ($weekstarts == DateTime::firstDayOfWeek($timezone, get_mrbs_locale()))) ? 'true' : 'false' ?>;
}

flatpickr('input[type="date"]', config);
Expand Down
34 changes: 34 additions & 0 deletions web/lib/MRBS/DateTime.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
declare(strict_types=1);
namespace MRBS;

use IntlCalendar;
use MRBS\ICalendar\RFC5545;
use UnexpectedValueException;

Expand Down Expand Up @@ -33,6 +34,39 @@ public static function createFromFormat($format, $datetime, ?\DateTimeZone $time
return new static($parent->format('Y-m-d\TH:i:s.u'), $parent->getTimezone());
}


// Returns the first day of the week (0 = Sunday) for a given timezone and locale.
// If $timezone is null, the default timezone will be used.
// If $locale is null, the default locale will be used.
// The method relies on the IntlCalendar class. If it doesn't exist, or there's an error,
// the method assumes that the week starts on a Monday.
public static function firstDayOfWeek(?string $timezone = null, ?string $locale = null) : int
{
$default = 1; // Monday

if (!class_exists('\\IntlCalendar'))
{
return $default;
}

$calendar = IntlCalendar::createInstance($timezone, $locale);
if (!isset($calendar))
{
trigger_error("Could not create IntlCalendar for timezone '$timezone' and locale '$locale'", E_USER_WARNING);
return $default;
}

$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
}


// TODO: replace usages of byday_to_day() with this method
// TODO: make $relative an object?
// Sets the day to $relative, where relative is an RFC5545 relative day,
Expand Down
18 changes: 10 additions & 8 deletions web/systemdefaults.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -436,11 +436,18 @@
// of 12.
$monthly_view_entries_details = "both";

// To show ISO week numbers in the main calendar, set this to true. The week
// numbers are only displayed if you set $weekstarts to 1 (Monday), i.e. the
// start of the ISO week.
// To show week numbers in the main calendar, set this to true. The week
// numbers are only displayed if you set $weekstarts to start on the first
// day of the week in your locale and area's timezone. (This assumes that
// the PHP IntlCalendar class is available; if not, the week is assumed to
// start on Mondays, ie the ISO stanard.)
$view_week_number = false;

// To display week numbers in the mini-calendars, set this to true. The week
// numbers are only displayed if you set $weekstarts to the start of the week.
// See the comment about when the week starts above.
$mincals_week_numbers = false;

// Whether or not the mini-calendars are displayed. (Note that mini-calendars are only
// displayed anyway if the window is wide enough.)
$display_mincals = true;
Expand All @@ -450,11 +457,6 @@
// provided the window is high enough.
$display_mincals_above = false;

// To display week numbers in the mini-calendars, set this to true. The week
// numbers are only displayed if you set $weekstarts to 1 (Monday), i.e. the
// start of the ISO week.
$mincals_week_numbers = false;

// To display the endtime in the slot description, eg '09:00-09:30' instead of '09:00', set
// this to true.
$show_slot_endtime = false;
Expand Down

0 comments on commit 1af44b8

Please sign in to comment.