diff --git a/glib/gtimezone.c b/glib/gtimezone.c index dd4948e62..0155a5841 100644 --- a/glib/gtimezone.c +++ b/glib/gtimezone.c @@ -1203,14 +1203,21 @@ parse_mwd_boundary (gchar **pos, TimeZoneDate *boundary) return TRUE; } -/* Different implementations of tzset interpret the Julian day field - differently. For example, Linux specifies that it should be 1-based - (1 Jan is JD 1) for both Jn and n formats, while zOS and BSD - specify that a Jn JD is 1-based while an n JD is 0-based. Rather - than trying to follow different specs, we will follow GDate's - practice thatIn order to keep it simple, we will follow Linux's - practice. */ - +/* + * This parses two slightly different ways of specifying + * the Julian day: + * + * - ignore_leap == TRUE + * + * Jn This specifies the Julian day with n between 1 and 365. Leap days + * are not counted. In this format, February 29 can't be represented; + * February 28 is day 59, and March 1 is always day 60. + * + * - ignore_leap == FALSE + * + * n This specifies the zero-based Julian day with n between 0 and 365. + * February 29 is counted in leap years. + */ static gboolean parse_julian_boundary (gchar** pos, TimeZoneDate *boundary, gboolean ignore_leap) @@ -1224,8 +1231,20 @@ parse_julian_boundary (gchar** pos, TimeZoneDate *boundary, day += *(*pos)++ - '0'; } - if (day < 1 || 365 < day) - return FALSE; + if (ignore_leap) + { + if (day < 1 || 365 < day) + return FALSE; + if (day >= 59) + day++; + } + else + { + if (day < 0 || 365 < day) + return FALSE; + /* GDate wants day in range 1->366 */ + day++; + } g_date_clear (&date, 1); g_date_set_julian (&date, day); @@ -1234,9 +1253,6 @@ parse_julian_boundary (gchar** pos, TimeZoneDate *boundary, boundary->mday = (int) g_date_get_day (&date); boundary->wday = 0; - if (ignore_leap && day >= 59) - boundary->mday++; - return TRUE; } diff --git a/glib/tests/gdatetime.c b/glib/tests/gdatetime.c index 174a1df14..c88b411ff 100644 --- a/glib/tests/gdatetime.c +++ b/glib/tests/gdatetime.c @@ -2432,8 +2432,8 @@ test_posix_parse (void) g_date_time_unref (gdt2); g_time_zone_unref (tz); - tz = g_time_zone_new ("NZST-12:00:00NZDT-13:00:00,280,77"); - g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "NZST-12:00:00NZDT-13:00:00,280,77"); + tz = g_time_zone_new ("NZST-12:00:00NZDT-13:00:00,279,76"); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "NZST-12:00:00NZDT-13:00:00,279,76"); g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "NZST"); g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, 12 * 3600); g_assert (!g_time_zone_is_dst (tz, 0)); @@ -2533,6 +2533,48 @@ test_posix_parse (void) g_date_time_unref (gdt1); g_date_time_unref (gdt2); g_time_zone_unref (tz); + + tz = g_time_zone_new ("VIR-00:30"); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-00:30"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (30 * 60)); + g_assert_false (g_time_zone_is_dst (tz, 0)); + + tz = g_time_zone_new ("VIR-00:30VID,0/00:00:00,365/23:59:59"); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-00:30VID,0/00:00:00,365/23:59:59"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (30 * 60)); + g_assert_false (g_time_zone_is_dst (tz, 0)); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "VID"); + g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, (90 * 60)); + g_assert_true (g_time_zone_is_dst (tz, 1)); + + tz = g_time_zone_new ("VIR-02:30VID,0/00:00:00,365/23:59:59"); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-02:30VID,0/00:00:00,365/23:59:59"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (150 * 60)); + g_assert_false (g_time_zone_is_dst (tz, 0)); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "VID"); + g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, (210 * 60)); + g_assert_true (g_time_zone_is_dst (tz, 1)); + + tz = g_time_zone_new ("VIR-02:30VID-04:30,0/00:00:00,365/23:59:59"); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-02:30VID-04:30,0/00:00:00,365/23:59:59"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (150 * 60)); + g_assert_false (g_time_zone_is_dst (tz, 0)); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "VID"); + g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, (270 * 60)); + g_assert_true (g_time_zone_is_dst (tz, 1)); + + tz = g_time_zone_new ("VIR-12:00VID-13:00,0/00:00:00,365/23:59:59"); + g_assert_cmpstr (g_time_zone_get_identifier (tz), ==, "VIR-12:00VID-13:00,0/00:00:00,365/23:59:59"); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 0), ==, "VIR"); + g_assert_cmpint (g_time_zone_get_offset (tz, 0), ==, (720 * 60)); + g_assert_false (g_time_zone_is_dst (tz, 0)); + g_assert_cmpstr (g_time_zone_get_abbreviation (tz, 1), ==, "VID"); + g_assert_cmpint (g_time_zone_get_offset (tz, 1), ==, (780 * 60)); + g_assert_true (g_time_zone_is_dst (tz, 1)); } static void