utils: Use ISO weekday numbering for 'get_first_weekday' function

Change the 'get_first_weekday' function to number the weekdays
Monday(1)-Sunday(7) like ISO does. Change the function name to reflect
that. Add tests for different locales, although the tests depend on
system-installed locales.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-calendar/-/merge_requests/822>
This commit is contained in:
mindonwarp
2026-09-26 17:22:00 +00:00
committed by Marge Bot
parent a0a6ae2a2c
commit acd8fbaf69
8 changed files with 74 additions and 25 deletions
+3 -3
View File
@@ -116,7 +116,7 @@ set_week_start_day_from_variant (GcalContext *self,
/* find the actual 'default' from locale */
if (weekday->value == G_DESKTOP_WEEKDAY_DEFAULT)
weekday = g_enum_get_value (g_type_class_get (G_DESKTOP_TYPE_WEEKDAY), gcal_util_get_first_weekday ());
weekday = g_enum_get_value (g_type_class_get (G_DESKTOP_TYPE_WEEKDAY), gcal_util_get_first_weekday_iso ());
if (self->week_start_day == weekday->value)
return;
@@ -391,7 +391,7 @@ gcal_context_class_init (GcalContextClass *klass)
properties[PROP_WEEK_START_DAY] =
g_param_spec_enum ("week-start-day", NULL, NULL,
G_DESKTOP_TYPE_WEEKDAY, gcal_util_get_first_weekday (),
G_DESKTOP_TYPE_WEEKDAY, gcal_util_get_first_weekday_iso (),
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
@@ -535,7 +535,7 @@ gcal_context_get_time_format (GcalContext *self)
GDesktopWeekday
gcal_context_get_week_start_day (GcalContext *self)
{
g_return_val_if_fail (GCAL_IS_CONTEXT (self), gcal_util_get_first_weekday ());
g_return_val_if_fail (GCAL_IS_CONTEXT (self), gcal_util_get_first_weekday_iso ());
return self->week_start_day;
}
+1 -1
View File
@@ -1083,7 +1083,7 @@ gcal_date_chooser_init (GcalDateChooser *self)
self->date = g_date_time_new_now_local ();
g_date_time_get_ymd (self->date, &self->this_year, NULL, NULL);
self->week_start = gcal_util_get_first_weekday ();
self->week_start = gcal_util_get_first_weekday_iso ();
gtk_widget_init_template (GTK_WIDGET (self));
+1 -1
View File
@@ -194,7 +194,7 @@ allocate_overflow_popover (GcalMonthView *self,
static inline void
update_weekday_labels (GcalMonthView *self)
{
const gint first_weekday = gcal_util_get_first_weekday ();
const gint first_weekday = gcal_util_get_first_weekday_iso ();
for (gint i = 0; i < GCAL_N_WEEKDAYS; i++)
{
-4
View File
@@ -100,8 +100,6 @@ struct _GcalWeekHeader
GtkWidget *overflow_label[GCAL_N_WEEKDAYS];
WeekdayHeader weekday_header[GCAL_N_WEEKDAYS];
gint first_weekday;
/*
* Used for checking if the header is in collapsed state or expand state
* false is collapse state true is expand state
@@ -1762,8 +1760,6 @@ gcal_week_header_init (GcalWeekHeader *self)
gtk_widget_set_visible (self->dnd.widget, FALSE);
gtk_widget_set_parent (self->dnd.widget, GTK_WIDGET (self));
self->first_weekday = gcal_util_get_first_weekday ();
gtk_widget_init_template (GTK_WIDGET (self));
for (i = 0; i < GCAL_N_WEEKDAYS; i++)
+1 -1
View File
@@ -83,7 +83,7 @@ gcal_date_time_get_start_of_week (GDateTime *date)
g_assert (date != NULL);
first_weekday = gcal_util_get_first_weekday ();
first_weekday = gcal_util_get_first_weekday_iso ();
weekday = g_date_time_get_day_of_week (date) % GCAL_N_WEEKDAYS;
n_days_after_week_start = (GCAL_N_WEEKDAYS + weekday - first_weekday) % GCAL_N_WEEKDAYS;
+24 -14
View File
@@ -213,36 +213,46 @@ gcal_util_get_desc_from_component (ECalComponent *component,
/**
* gcal_util_get_first_weekday:
*
* Copied from Clocks, which by itself is
* copied from GtkCalendar.
* Finds the locale default first day of week
* respecting the ISO day counting (Monday: 1 - Sunday: 7).
*
* Returns: the first weekday, from 0 to 6
* Prefer using `GcalContext:week-start-day` property or
* the `GcalContext:gcal_context_get_week_start_day()` method
* to get the current setting from gsettings-desktop-schemas.
* Use this utility method only as a fallback.
*
* Returns: the first weekday, from 1 to 7
*/
gint
gcal_util_get_first_weekday (void)
gcal_util_get_first_weekday_iso (void)
{
gint week_start;
#ifdef HAVE__NL_TIME_FIRST_WEEKDAY
union { unsigned int word; char *string; } langinfo;
gint week_1stday = 0;
union { unsigned int baseline; char *offset; } langinfo;
gint iso_week_base = 7; /* default to Sunday (19971130) */
gint first_weekday = 1;
guint week_origin;
langinfo.string = nl_langinfo (_NL_TIME_FIRST_WEEKDAY);
first_weekday = langinfo.string[0];
langinfo.string = nl_langinfo (_NL_TIME_WEEK_1STDAY);
week_origin = langinfo.word;
/* first day of week index */
langinfo.offset = nl_langinfo (_NL_TIME_FIRST_WEEKDAY);
first_weekday = langinfo.offset[0];
/* find the baseline week origin */
langinfo.offset = nl_langinfo (_NL_TIME_WEEK_1STDAY);
week_origin = langinfo.baseline;
if (week_origin == 19971130) /* Sunday */
week_1stday = 0;
iso_week_base = 7;
else if (week_origin == 19971201) /* Monday */
week_1stday = 1;
iso_week_base = 1;
else if (week_origin == 19971129) /* unusual: Saturday */
iso_week_base = 6;
else
g_warning ("Unknown value of _NL_TIME_WEEK_1STDAY.\n");
week_start = (week_1stday + first_weekday - 1) % GCAL_N_WEEKDAYS;
week_start = ((iso_week_base - 1 + (first_weekday - 1)) % GCAL_N_WEEKDAYS) + 1;
#else
gchar *gtk_week_start;
+1 -1
View File
@@ -63,7 +63,7 @@ GdkPaintable* gcal_util_get_circle_paintable_from_color (const GdkRGBA
gchar* gcal_util_get_desc_from_component (ECalComponent *component,
const gchar *joint_char);
gint gcal_util_get_first_weekday (void);
gint gcal_util_get_first_weekday_iso (void);
ECalComponent* gcal_util_build_component_from_details (const gchar *summary,
GDateTime *initial_date,
+43
View File
@@ -17,6 +17,7 @@
*/
#include <glib.h>
#include <locale.h>
#include "gcal-utils.h"
@@ -191,6 +192,47 @@ extract_meeting_url (void)
/*********************************************************************************************************************/
typedef struct {
const char *locale_name;
int week_start_index;
} LocaleIsoWeekDay;
static void
test_first_weekday (void)
{
LocaleIsoWeekDay test_cases[] = {
{ "C", 7 }, // Baseline standard (Sunday)
{ "en_US.UTF-8", 7 }, // US Standard (Sunday)
{ "de_DE.UTF-8", 1 }, // Euro Standard (Monday)
{ "en_GB.UTF-8", 1 }, // UK Standard (Monday)
{ "fa_IR.UTF-8", 6 } // Iran, Somalia, Afghanistan (Saturday)
};
const char* initial_locale = setlocale (LC_ALL, NULL);
for (size_t i = 0; i < G_N_ELEMENTS (test_cases); ++i)
{
LocaleIsoWeekDay testcase = test_cases[i];
char *current_locale = setlocale (LC_ALL, testcase.locale_name);
if (!current_locale)
{
g_message ("Locale %s not installed. Skipping", testcase.locale_name);
continue;
}
else
{
g_message ("Testing locale %s", testcase.locale_name);
g_assert_cmpint (testcase.week_start_index, ==, gcal_util_get_first_weekday_iso ());
}
}
/* restore locale */
setlocale (LC_ALL, initial_locale);
}
/*********************************************************************************************************************/
gint
main (gint argc,
gchar *argv[])
@@ -202,6 +244,7 @@ main (gint argc,
g_test_add_func ("/utils/date-time/date_time_from_icaltime", date_time_from_icaltime);
g_test_add_func ("/utils/misc/extract_meeting_url", extract_meeting_url);
g_test_add_func ("/utils/misc/get_first_weekday", test_first_weekday);
return g_test_run ();
}