changeset 18875:affde4311db7

tzset: Expand comment about TZ problem on native Windows. * lib/tzset.c (tzset): Elaborate comment, based on explanations by Paul Eggert. * lib/ctime.c (rpl_ctime): Likewise. * lib/localtime.c (rpl_localtime): Likewise. * lib/mktime.c (mktime): Likewise. * lib/strftime-fixes.c (rpl_strftime): Likewise. * lib/wcsftime.c (rpl_wcsftime): Likewise.
author Bruno Haible <bruno@clisp.org>
date Tue, 09 May 2017 21:27:27 +0200
parents b42957bdcc40
children 7b2eb2c8d463
files ChangeLog lib/ctime.c lib/localtime.c lib/mktime.c lib/strftime-fixes.c lib/tzset.c lib/wcsftime.c
diffstat 7 files changed, 143 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon May 08 10:37:48 2017 -0700
+++ b/ChangeLog	Tue May 09 21:27:27 2017 +0200
@@ -1,3 +1,14 @@
+2017-05-09 Bruno Haible  <bruno@clisp.org>
+
+	tzset: Expand comment about TZ problem on native Windows.
+	* lib/tzset.c (tzset): Elaborate comment, based on explanations by
+	Paul Eggert.
+	* lib/ctime.c (rpl_ctime): Likewise.
+	* lib/localtime.c (rpl_localtime): Likewise.
+	* lib/mktime.c (mktime): Likewise.
+	* lib/strftime-fixes.c (rpl_strftime): Likewise.
+	* lib/wcsftime.c (rpl_wcsftime): Likewise.
+
 2017-05-08  Paul Eggert  <eggert@cs.ucla.edu>
 
 	intprops: don’t depend on ‘verify’
--- a/lib/ctime.c	Mon May 08 10:37:48 2017 -0700
+++ b/lib/ctime.c	Tue May 09 21:27:27 2017 +0200
@@ -28,9 +28,28 @@
 rpl_ctime (const time_t *tp)
 {
 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
-  /* If the environment variable TZ has been set by Cygwin, neutralize it.
-     The Microsoft CRT interprets TZ differently than Cygwin and produces
-     incorrect results if TZ has the syntax used by Cygwin.  */
+  /* Rectify the value of the environment variable TZ.
+     There are four possible kinds of such values:
+       - Traditional US time zone names, e.g. "PST8PDT".  Syntax: see
+         <https://msdn.microsoft.com/en-us/library/90s5c885.aspx>
+       - Time zone names based on geography, that contain one or more
+         slashes, e.g. "Europe/Moscow".
+       - Time zone names based on geography, without slashes, e.g.
+         "Singapore".
+       - Time zone names that contain explicit DST rules.  Syntax: see
+         <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03>
+     The Microsoft CRT understands only the first kind.  It produces incorrect
+     results if the value of TZ is of the other kinds.
+     But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value
+     of the second kind for most geographies, or of the first kind in a few
+     other geographies.  If it is of the second kind, neutralize it.  For the
+     Microsoft CRT, an absent or empty TZ means the time zone that the user
+     has set in the Windows Control Panel.
+     If the value of TZ is of the third or fourth kind -- Cygwin programs
+     understand these syntaxes as well --, it does not matter whether we
+     neutralize it or not, since these values occur only when a Cygwin user
+     has set TZ explicitly; this case is 1. rare and 2. under the user's
+     responsibility.  */
   const char *tz = getenv ("TZ");
   if (tz != NULL && strchr (tz, '/') != NULL)
     _putenv ("TZ=");
--- a/lib/localtime.c	Mon May 08 10:37:48 2017 -0700
+++ b/lib/localtime.c	Tue May 09 21:27:27 2017 +0200
@@ -31,9 +31,28 @@
 rpl_localtime (const time_t *tp)
 {
 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
-  /* If the environment variable TZ has been set by Cygwin, neutralize it.
-     The Microsoft CRT interprets TZ differently than Cygwin and produces
-     incorrect results if TZ has the syntax used by Cygwin.  */
+  /* Rectify the value of the environment variable TZ.
+     There are four possible kinds of such values:
+       - Traditional US time zone names, e.g. "PST8PDT".  Syntax: see
+         <https://msdn.microsoft.com/en-us/library/90s5c885.aspx>
+       - Time zone names based on geography, that contain one or more
+         slashes, e.g. "Europe/Moscow".
+       - Time zone names based on geography, without slashes, e.g.
+         "Singapore".
+       - Time zone names that contain explicit DST rules.  Syntax: see
+         <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03>
+     The Microsoft CRT understands only the first kind.  It produces incorrect
+     results if the value of TZ is of the other kinds.
+     But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value
+     of the second kind for most geographies, or of the first kind in a few
+     other geographies.  If it is of the second kind, neutralize it.  For the
+     Microsoft CRT, an absent or empty TZ means the time zone that the user
+     has set in the Windows Control Panel.
+     If the value of TZ is of the third or fourth kind -- Cygwin programs
+     understand these syntaxes as well --, it does not matter whether we
+     neutralize it or not, since these values occur only when a Cygwin user
+     has set TZ explicitly; this case is 1. rare and 2. under the user's
+     responsibility.  */
   const char *tz = getenv ("TZ");
   if (tz != NULL && strchr (tz, '/') != NULL)
     _putenv ("TZ=");
--- a/lib/mktime.c	Mon May 08 10:37:48 2017 -0700
+++ b/lib/mktime.c	Tue May 09 21:27:27 2017 +0200
@@ -491,9 +491,28 @@
 mktime (struct tm *tp)
 {
 # if NEED_MKTIME_WINDOWS
-  /* If the environment variable TZ has been set by Cygwin, neutralize it.
-     The Microsoft CRT interprets TZ differently than Cygwin and produces
-     incorrect results if TZ has the syntax used by Cygwin.  */
+  /* Rectify the value of the environment variable TZ.
+     There are four possible kinds of such values:
+       - Traditional US time zone names, e.g. "PST8PDT".  Syntax: see
+         <https://msdn.microsoft.com/en-us/library/90s5c885.aspx>
+       - Time zone names based on geography, that contain one or more
+         slashes, e.g. "Europe/Moscow".
+       - Time zone names based on geography, without slashes, e.g.
+         "Singapore".
+       - Time zone names that contain explicit DST rules.  Syntax: see
+         <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03>
+     The Microsoft CRT understands only the first kind.  It produces incorrect
+     results if the value of TZ is of the other kinds.
+     But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value
+     of the second kind for most geographies, or of the first kind in a few
+     other geographies.  If it is of the second kind, neutralize it.  For the
+     Microsoft CRT, an absent or empty TZ means the time zone that the user
+     has set in the Windows Control Panel.
+     If the value of TZ is of the third or fourth kind -- Cygwin programs
+     understand these syntaxes as well --, it does not matter whether we
+     neutralize it or not, since these values occur only when a Cygwin user
+     has set TZ explicitly; this case is 1. rare and 2. under the user's
+     responsibility.  */
   const char *tz = getenv ("TZ");
   if (tz != NULL && strchr (tz, '/') != NULL)
     _putenv ("TZ=");
--- a/lib/strftime-fixes.c	Mon May 08 10:37:48 2017 -0700
+++ b/lib/strftime-fixes.c	Tue May 09 21:27:27 2017 +0200
@@ -28,9 +28,28 @@
 rpl_strftime (char *buf, size_t bufsize, const char *format, const struct tm *tp)
 {
 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
-  /* If the environment variable TZ has been set by Cygwin, neutralize it.
-     The Microsoft CRT interprets TZ differently than Cygwin and produces
-     incorrect results if TZ has the syntax used by Cygwin.  */
+  /* Rectify the value of the environment variable TZ.
+     There are four possible kinds of such values:
+       - Traditional US time zone names, e.g. "PST8PDT".  Syntax: see
+         <https://msdn.microsoft.com/en-us/library/90s5c885.aspx>
+       - Time zone names based on geography, that contain one or more
+         slashes, e.g. "Europe/Moscow".
+       - Time zone names based on geography, without slashes, e.g.
+         "Singapore".
+       - Time zone names that contain explicit DST rules.  Syntax: see
+         <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03>
+     The Microsoft CRT understands only the first kind.  It produces incorrect
+     results if the value of TZ is of the other kinds.
+     But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value
+     of the second kind for most geographies, or of the first kind in a few
+     other geographies.  If it is of the second kind, neutralize it.  For the
+     Microsoft CRT, an absent or empty TZ means the time zone that the user
+     has set in the Windows Control Panel.
+     If the value of TZ is of the third or fourth kind -- Cygwin programs
+     understand these syntaxes as well --, it does not matter whether we
+     neutralize it or not, since these values occur only when a Cygwin user
+     has set TZ explicitly; this case is 1. rare and 2. under the user's
+     responsibility.  */
   const char *tz = getenv ("TZ");
   if (tz != NULL && strchr (tz, '/') != NULL)
     _putenv ("TZ=");
--- a/lib/tzset.c	Mon May 08 10:37:48 2017 -0700
+++ b/lib/tzset.c	Tue May 09 21:27:27 2017 +0200
@@ -41,9 +41,28 @@
 #endif
 
 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
-  /* If the environment variable TZ has been set by Cygwin, neutralize it.
-     The Microsoft CRT interprets TZ differently than Cygwin and produces
-     incorrect results if TZ has the syntax used by Cygwin.  */
+  /* Rectify the value of the environment variable TZ.
+     There are four possible kinds of such values:
+       - Traditional US time zone names, e.g. "PST8PDT".  Syntax: see
+         <https://msdn.microsoft.com/en-us/library/90s5c885.aspx>
+       - Time zone names based on geography, that contain one or more
+         slashes, e.g. "Europe/Moscow".
+       - Time zone names based on geography, without slashes, e.g.
+         "Singapore".
+       - Time zone names that contain explicit DST rules.  Syntax: see
+         <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03>
+     The Microsoft CRT understands only the first kind.  It produces incorrect
+     results if the value of TZ is of the other kinds.
+     But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value
+     of the second kind for most geographies, or of the first kind in a few
+     other geographies.  If it is of the second kind, neutralize it.  For the
+     Microsoft CRT, an absent or empty TZ means the time zone that the user
+     has set in the Windows Control Panel.
+     If the value of TZ is of the third or fourth kind -- Cygwin programs
+     understand these syntaxes as well --, it does not matter whether we
+     neutralize it or not, since these values occur only when a Cygwin user
+     has set TZ explicitly; this case is 1. rare and 2. under the user's
+     responsibility.  */
   const char *tz = getenv ("TZ");
   if (tz != NULL && strchr (tz, '/') != NULL)
     _putenv ("TZ=");
--- a/lib/wcsftime.c	Mon May 08 10:37:48 2017 -0700
+++ b/lib/wcsftime.c	Tue May 09 21:27:27 2017 +0200
@@ -29,9 +29,28 @@
 rpl_wcsftime (wchar_t *buf, size_t bufsize, const wchar_t *format, const struct tm *tp)
 {
 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
-  /* If the environment variable TZ has been set by Cygwin, neutralize it.
-     The Microsoft CRT interprets TZ differently than Cygwin and produces
-     incorrect results if TZ has the syntax used by Cygwin.  */
+  /* Rectify the value of the environment variable TZ.
+     There are four possible kinds of such values:
+       - Traditional US time zone names, e.g. "PST8PDT".  Syntax: see
+         <https://msdn.microsoft.com/en-us/library/90s5c885.aspx>
+       - Time zone names based on geography, that contain one or more
+         slashes, e.g. "Europe/Moscow".
+       - Time zone names based on geography, without slashes, e.g.
+         "Singapore".
+       - Time zone names that contain explicit DST rules.  Syntax: see
+         <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03>
+     The Microsoft CRT understands only the first kind.  It produces incorrect
+     results if the value of TZ is of the other kinds.
+     But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value
+     of the second kind for most geographies, or of the first kind in a few
+     other geographies.  If it is of the second kind, neutralize it.  For the
+     Microsoft CRT, an absent or empty TZ means the time zone that the user
+     has set in the Windows Control Panel.
+     If the value of TZ is of the third or fourth kind -- Cygwin programs
+     understand these syntaxes as well --, it does not matter whether we
+     neutralize it or not, since these values occur only when a Cygwin user
+     has set TZ explicitly; this case is 1. rare and 2. under the user's
+     responsibility.  */
   const char *tz = getenv ("TZ");
   if (tz != NULL && strchr (tz, '/') != NULL)
     _putenv ("TZ=");