Subject: bug#21126: Merge gnulib time_rz changes into coreutils

From: Paul Eggert <[email-masked]>
Date: Thu, 23 Jul 2015 18:55:14 -0700

Tags: patch

I just installed some incompatible changes into gnulib for time zone handling. 
The attached patches (just installed into coreutils) makes coreutils work with 
the new API.

Eventually, I hope to get this new API into glibc, but one thing at a time.
>From 0806daf566f36940ec71306b6c519b3038bef9e6 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Thu, 23 Jul 2015 18:33:59 -0700
Subject: [PATCH 1/2] build: update gnulib submodule to latest

---
 gnulib | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gnulib b/gnulib
index d03962a..a89e344 160000
--- a/gnulib
+++ b/gnulib
@@ -1 +1 @@
-Subproject commit d03962a999263ee24acbf4fe1f87eecdd2b7ba71
+Subproject commit a89e3449698f97ea0f9c5fbd73aa054009858471
-- 
2.1.0

>From 74674a1fa303e3637a03ea695ffd4564f412d766 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Thu, 23 Jul 2015 18:49:31 -0700
Subject: [PATCH 2/2] build: fprintftime/nstrftime API changes

* bootstrap.conf (gnulib_modules): Add time_rz,
since the main source code now uses timezone_t.
* src/date.c (batch_convert, main, show_date):
* src/ls.c (align_nstrftime, long_time_expected_width)
(print_long_format):
* src/stat.c (human_time):
Use timezone_t rather than boolean to specify which time zone
is wanted.
* src/ls.c (localtz): New static var.
(main): Initialize it.
---
 bootstrap.conf |  1 +
 src/date.c     | 16 +++++++++-------
 src/ls.c       | 15 +++++++++++----
 src/stat.c     |  5 ++++-
 4 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/bootstrap.conf b/bootstrap.conf
index 67837b3..5c6d2bf 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -240,6 +240,7 @@ gnulib_modules="
   sys_wait
   tempname
   termios
+  time_rz
   timer-time
   timespec
   tzset
diff --git a/src/date.c b/src/date.c
index eaee8b2..fae0256 100644
--- a/src/date.c
+++ b/src/date.c
@@ -38,7 +38,7 @@
 
 #define AUTHORS proper_name ("David MacKenzie")
 
-static bool show_date (const char *format, struct timespec when);
+static bool show_date (const char *, struct timespec, timezone_t);
 
 enum Time_spec
 {
@@ -272,7 +272,7 @@ Show the local time for 9AM next Friday on the west coast of the US\n\
    Return true if successful.  */
 
 static bool
-batch_convert (const char *input_filename, const char *format)
+batch_convert (const char *input_filename, const char *format, timezone_t tz)
 {
   bool ok;
   FILE *in_stream;
@@ -315,7 +315,7 @@ batch_convert (const char *input_filename, const char *format)
         }
       else
         {
-          ok &= show_date (format, when);
+          ok &= show_date (format, when, tz);
         }
     }
 
@@ -485,8 +485,10 @@ main (int argc, char **argv)
         }
     }
 
+  timezone_t tz = tzalloc (getenv ("TZ"));
+
   if (batch_file != NULL)
-    ok = batch_convert (batch_file, format);
+    ok = batch_convert (batch_file, format, tz);
   else
     {
       bool valid_date = true;
@@ -543,7 +545,7 @@ main (int argc, char **argv)
             }
         }
 
-      ok &= show_date (format, when);
+      ok &= show_date (format, when, tz);
     }
 
   return ok ? EXIT_SUCCESS : EXIT_FAILURE;
@@ -553,7 +555,7 @@ main (int argc, char **argv)
    in FORMAT, followed by a newline.  Return true if successful.  */
 
 static bool
-show_date (const char *format, struct timespec when)
+show_date (const char *format, struct timespec when, timezone_t tz)
 {
   struct tm *tm;
 
@@ -567,7 +569,7 @@ show_date (const char *format, struct timespec when)
 
   if (format == rfc_2822_format)
     setlocale (LC_TIME, "C");
-  fprintftime (stdout, format, tm, 0, when.tv_nsec);
+  fprintftime (stdout, format, tm, tz, when.tv_nsec);
   fputc ('\n', stdout);
   if (format == rfc_2822_format)
     setlocale (LC_TIME, "");
diff --git a/src/ls.c b/src/ls.c
index 6860dd4..fe95a46 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -699,6 +699,10 @@ static bool print_dir_name;
 
 static size_t line_length;
 
+/* The local time zone rules, as per the TZ environment variable.  */
+
+static timezone_t localtz;
+
 /* If true, the file listing format requires that stat be called on
    each file.  */
 
@@ -1374,6 +1378,8 @@ main (int argc, char **argv)
       obstack_init (&dev_ino_obstack);
     }
 
+  localtz = tzalloc (getenv ("TZ"));
+
   format_needs_stat = sort_type == sort_time || sort_type == sort_size
     || format == long_format
     || print_scontext
@@ -3654,7 +3660,7 @@ print_current_files (void)
 
 static size_t
 align_nstrftime (char *buf, size_t size, char const *fmt, struct tm const *tm,
-                 int __utc, int __ns)
+                 timezone_t tz, int ns)
 {
   const char *nfmt = fmt;
   /* In the unlikely event that rpl_fmt below is not large enough,
@@ -3674,7 +3680,7 @@ align_nstrftime (char *buf, size_t size, char const *fmt, struct tm const *tm,
           strcpy (pfmt, pb + 2);
         }
     }
-  size_t ret = nstrftime (buf, size, nfmt, tm, __utc, __ns);
+  size_t ret = nstrftime (buf, size, nfmt, tm, tz, ns);
   return ret;
 }
 
@@ -3702,7 +3708,8 @@ long_time_expected_width (void)
       if (tm)
         {
           size_t len =
-            align_nstrftime (buf, sizeof buf, long_time_format[0], tm, 0, 0);
+            align_nstrftime (buf, sizeof buf, long_time_format[0], tm,
+                             localtz, 0);
           if (len != 0)
             width = mbsnwidth (buf, len, 0);
         }
@@ -3987,7 +3994,7 @@ print_long_format (const struct fileinfo *f)
       /* We assume here that all time zones are offset from UTC by a
          whole number of seconds.  */
       s = align_nstrftime (p, TIME_STAMP_LEN_MAXIMUM + 1, fmt,
-                           when_local, 0, when_timespec.tv_nsec);
+                           when_local, localtz, when_timespec.tv_nsec);
     }
 
   if (s || !*p)
diff --git a/src/stat.c b/src/stat.c
index 6d23665..680a598 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -547,10 +547,13 @@ human_time (struct timespec t)
                        (INT_STRLEN_BOUND (int) /* YYYY */
                         + 1 /* because YYYY might equal INT_MAX + 1900 */
                         + sizeof "-MM-DD HH:MM:SS.NNNNNNNNN +ZZZZ"))];
+  static timezone_t tz;
+  if (!tz)
+    tz = tzalloc (getenv ("TZ"));
   struct tm const *tm = localtime (&t.tv_sec);
   if (tm == NULL)
     return timetostr (t.tv_sec, str);
-  nstrftime (str, sizeof str, "%Y-%m-%d %H:%M:%S.%N %z", tm, 0, t.tv_nsec);
+  nstrftime (str, sizeof str, "%Y-%m-%d %H:%M:%S.%N %z", tm, tz, t.tv_nsec);
   return str;
 }
 
-- 
2.1.0