From: Bruno Haible Date: Tue, 9 May 2017 19:27:27 +0000 (+0200) Subject: tzset: Expand comment about TZ problem on native Windows. X-Git-Tag: v1.0~6184 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=aca75e962fd394c5c19dd9a9544b19a233edde30;p=thirdparty%2Fgnulib.git 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. --- diff --git a/ChangeLog b/ChangeLog index b159e4a5d3..ff44fbc57b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2017-05-09 Bruno Haible + + 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 intprops: don’t depend on ‘verify’ diff --git a/lib/ctime.c b/lib/ctime.c index 16416ab8f4..4fe7d57efe 100644 --- a/lib/ctime.c +++ b/lib/ctime.c @@ -28,9 +28,28 @@ char * 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 + + - 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 + + 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="); diff --git a/lib/localtime.c b/lib/localtime.c index 5316930b67..987d9aa15d 100644 --- a/lib/localtime.c +++ b/lib/localtime.c @@ -31,9 +31,28 @@ struct tm * 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 + + - 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 + + 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="); diff --git a/lib/mktime.c b/lib/mktime.c index a78d960e53..72df770c1a 100644 --- a/lib/mktime.c +++ b/lib/mktime.c @@ -491,9 +491,28 @@ time_t 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 + + - 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 + + 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="); diff --git a/lib/strftime-fixes.c b/lib/strftime-fixes.c index 6618c13491..065fdafa2d 100644 --- a/lib/strftime-fixes.c +++ b/lib/strftime-fixes.c @@ -28,9 +28,28 @@ size_t 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 + + - 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 + + 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="); diff --git a/lib/tzset.c b/lib/tzset.c index ce854b9f11..bec4dfe620 100644 --- a/lib/tzset.c +++ b/lib/tzset.c @@ -41,9 +41,28 @@ tzset (void) #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 + + - 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 + + 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="); diff --git a/lib/wcsftime.c b/lib/wcsftime.c index cffe2e0932..846b981094 100644 --- a/lib/wcsftime.c +++ b/lib/wcsftime.c @@ -29,9 +29,28 @@ size_t 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 + + - 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 + + 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=");