[tz] setting TZ and calling localtime_r

Guy Harris guy at alum.mit.edu
Fri Dec 15 09:25:37 UTC 2017

On Dec 15, 2017, at 12:37 AM, Steve Summit <scs at eskimo.com> wrote:

> There's code in tzcode (and, I suspect not coincidentally,
> glibc's localtime implementation as well) to not call the
> internal version of tzset on calls to localtime_r, but rather
> only on calls to localtime.  The justification is that Posix says
> localtime_r doesn't need to update the global tzname variable.
> I don't have a copy of the Posix spec handy,


You'll need to set up a free account to read it.

> so I can't check:
> does Posix also say that localtime_r doesn't need to check for
> and make use of a possibly-changed value of TZ?

It doesn't say that, but it also doesn't say it *does* need to.

The tzset() page:



	The tzset() function shall use the value of the environment variable TZ to set time conversion information used by ctime, localtime, mktime, and strftime. If TZ is absent from the environment, implementation-defined default timezone information shall be used.

but says nothing about what localtime_r() uses.

The informative (rather than normative) APPLICATION USAGE section of that page says

	Since the ctime(), localtime(), mktime(), strftime(), and strftime_l() functions are required to set timezone information as if by callingtzset(), there is no need for an explicit tzset() call before using these functions. However, portable applications should call tzset() explicitly before using ctime_r() or localtime_r() because setting timezone information is optional for those functions.

which appears to imply that acting as if tzset() were called, and *not* acting as if tzset() were called, are both possible.

The "Environment Variables" page:



		This variable shall represent timezone information. The contents of the environment variable named TZ shall be used by the ctime(), ctime_r(), localtime(), localtime_r() strftime(), mktime(), functions, and by various utilities, to override the default timezone. ...

so, as I read the Single UNIX Specification, localtime_r() (not surprisingly) honors TZ, but does not necessarily honor *changes* in TZ unless you call tzset() before calling localtime_r().

(BTW, macOS Sierra wants to autocorrect "tzset" to "taser".)

More information about the tz mailing list