datetime: Fix handling of Irish timezone on map

The timezone map tries to highlight regions of the world that keep the
same time, approximating this by their non-daylight-savings UTC offset.
There's no reasonable API for this, and it goes wrong in various cases,
such as Irish Standard Time which is legally defined as the country's
summer time with a negative DST offset in winter.

Hardcoding this is unpleasant, but there doesn't seem to be a better
solution, and in any case there's already similar hardcoding implied by
the segmented map images in panels/datetime/data/timezone_*.png.  I've
tried to make it practical to fix other similar disagreements between
the detected offset and the groupings implied by map images, though for
now I've conservatively fixed only the case I'm familiar with.

Fixes: #1341
This commit is contained in:
Colin Watson 2021-09-27 23:36:29 +01:00
parent 1b874509a4
commit 14a2672e28
3 changed files with 37 additions and 5 deletions

View file

@ -426,8 +426,8 @@ set_location (CcTimezoneMap *map,
info = tz_info_from_location (map->location);
map->selected_offset = tz_location_get_utc_offset (map->location)
/ (60.0*60.0) + ((info->daylight) ? -1.0 : 0.0);
map->selected_offset = tz_location_get_base_utc_offset (map->location)
/ (60.0*60.0);
gtk_widget_queue_draw (GTK_WIDGET (map));
g_signal_emit (map, signals[LOCATION_CHANGED], 0, map->location);

View file

@ -181,14 +181,46 @@ tz_location_get_position (TzLocation *loc, double *longitude, double *latitude)
*latitude = loc->latitude;
}
/* For timezone map display purposes, we try to highlight regions of the
* world that keep the same time. There is no reasonable API to discover
* this; at the moment we just group timezones by their non-daylight-savings
* UTC offset and hope that's good enough. However, in some cases that
* produces confusing results. For example, Irish Standard Time is legally
* defined as the country's summer time, with a negative DST offset in
* winter; but this results in the same observed clock times as countries
* that observe Western European (Summer) Time, not those that observe
* Central European (Summer) Time, so we should group Ireland with the
* former, matching the grouping implied by data/timezone_*.png.
*
* This is something of a hack, and there remain other problems with
* timezone grouping: for example, grouping timezones north and south of the
* equator together where DST is observed at different times of the year is
* dubious.
*/
struct {
const char *zone;
gint offset;
} base_offset_overrides[] = {
{ "Europe/Dublin", 0 },
};
glong
tz_location_get_utc_offset (TzLocation *loc)
tz_location_get_base_utc_offset (TzLocation *loc)
{
g_autoptr(TzInfo) tz_info = NULL;
glong offset;
guint i;
tz_info = tz_info_from_location (loc);
offset = tz_info->utc_offset;
offset = tz_info->utc_offset + (tz_info->daylight ? -3600 : 0);
for (i = 0; i < G_N_ELEMENTS (base_offset_overrides); i++) {
if (g_str_equal (loc->zone, base_offset_overrides[i].zone)) {
offset = base_offset_overrides[i].offset;
break;
}
}
return offset;
}

View file

@ -78,7 +78,7 @@ void tz_location_get_position (TzLocation *loc,
char *tz_location_get_country (TzLocation *loc);
gchar *tz_location_get_zone (TzLocation *loc);
gchar *tz_location_get_comment (TzLocation *loc);
glong tz_location_get_utc_offset (TzLocation *loc);
glong tz_location_get_base_utc_offset (TzLocation *loc);
gint tz_location_set_locally (TzLocation *loc);
TzInfo *tz_info_from_location (TzLocation *loc);
void tz_info_free (TzInfo *tz_info);