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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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++)
|
||||
{
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user