[glib: 1/2] gdatetime: Fix formatting of time zones offsets in range -01:00 to +00:00



commit 54c394a73f95eb225fd748aef9a7205d45ff16fc
Author: Tomasz Miąsko <tomasz miasko gmail com>
Date:   Wed Oct 31 00:00:00 2018 +0000

    gdatetime: Fix formatting of time zones offsets in range -01:00 to +00:00
    
    Formatting code for `%z` specifier incorrectly assumed that sign of
    offset from UTC can be recovered from the number of hours alone, which
    is not true for offsets between -01:00 and +00:00.
    
    Extract and format sign separately to avoid the problem.
    
    Issue #1337.

 glib/gdatetime.c       | 17 +++++++++++------
 glib/tests/gdatetime.c | 22 ++++++++++++++++++++++
 2 files changed, 33 insertions(+), 6 deletions(-)
---
diff --git a/glib/gdatetime.c b/glib/gdatetime.c
index 1bd916587..32fd501aa 100644
--- a/glib/gdatetime.c
+++ b/glib/gdatetime.c
@@ -2721,34 +2721,39 @@ format_z (GString *outstr,
   gint hours;
   gint minutes;
   gint seconds;
+  gchar sign = offset >= 0 ? '+' : '-';
 
+  offset = ABS (offset);
   hours = offset / 3600;
-  minutes = ABS (offset) / 60 % 60;
-  seconds = ABS (offset) % 60;
+  minutes = offset / 60 % 60;
+  seconds = offset % 60;
 
   switch (colons)
     {
     case 0:
-      g_string_append_printf (outstr, "%+03d%02d",
+      g_string_append_printf (outstr, "%c%02d%02d",
+                              sign,
                               hours,
                               minutes);
       break;
 
     case 1:
-      g_string_append_printf (outstr, "%+03d:%02d",
+      g_string_append_printf (outstr, "%c%02d:%02d",
+                              sign,
                               hours,
                               minutes);
       break;
 
     case 2:
-      g_string_append_printf (outstr, "%+03d:%02d:%02d",
+      g_string_append_printf (outstr, "%c%02d:%02d:%02d",
+                              sign,
                               hours,
                               minutes,
                               seconds);
       break;
 
     case 3:
-      g_string_append_printf (outstr, "%+03d", hours);
+      g_string_append_printf (outstr, "%c%02d", sign, hours);
 
       if (minutes != 0 || seconds != 0)
         {
diff --git a/glib/tests/gdatetime.c b/glib/tests/gdatetime.c
index a028f6d20..f4000d96c 100644
--- a/glib/tests/gdatetime.c
+++ b/glib/tests/gdatetime.c
@@ -1986,6 +1986,28 @@ test_z (void)
   g_free (p);
   g_date_time_unref (dt);
   g_time_zone_unref (tz);
+
+  tz = g_time_zone_new ("-00:15");
+  dt = g_date_time_new (tz, 1, 1, 1, 0, 0, 0);
+
+  p = g_date_time_format (dt, "%z");
+  g_assert_cmpstr (p, ==, "-0015");
+  g_free (p);
+
+  p = g_date_time_format (dt, "%:z");
+  g_assert_cmpstr (p, ==, "-00:15");
+  g_free (p);
+
+  p = g_date_time_format (dt, "%::z");
+  g_assert_cmpstr (p, ==, "-00:15:00");
+  g_free (p);
+
+  p = g_date_time_format (dt, "%:::z");
+  g_assert_cmpstr (p, ==, "-00:15");
+  g_free (p);
+
+  g_date_time_unref (dt);
+  g_time_zone_unref (tz);
 }
 
 #pragma GCC diagnostic push


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]