Reentrant versions of localtime and gmtime.

Paul Eggert eggert at
Tue Oct 31 04:05:25 UTC 1995

   Date: Mon, 30 Oct 1995 17:13:53 -0800
   From: "J.T. Conklin" <jtc at>

     struct tm *
   + localtime_r(timep, res)
   + const time_t * const    timep;
   + struct tm *             tm;
   + {
   + 	tzset();
   + 	localsub(timep, 0L, tm);
   + 	return tm;
   + }

That isn't reentrant, since tzset() isn't reentrant.

   Date: Mon, 30 Oct 1995 17:58:13 -0800
   From: "J.T. Conklin" <jtc at>

   I discovered that most systems declare these as:
	   int asctime_r (const struct tm *, char *, int);
	   int ctime_r (const time_t *, char *, int);

   while Solaris provides:
	   char *asctime_r (const struct tm *, char *, int);
	   char *ctime_r (const time_t *, char *, int);
	   char *asctime_r (const struct tm *, char *)
	   char *ctime_r (const time_t *, char *);

Sun bug 1185180 claims that the last pair of prototypes appears in
Posix.1c draft 10.  Solaris 2.5 will be Posix.1c compliant.

Sorry, I don't have a copy of Posix.1c -- it hasn't been released to
the public yet as far as I know.  So I don't know whether the <time.h>
interfaces changed again between draft 10 and the official version.

I hope Posix.1c casts light on the tzset problem.

Also, in Solaris 2.4, <time.h> doesn't declare localtime_r,
gmtime_r, etc., unless _REENTRANT is #defined.  I don't know why this is.

Given the problems with tzset, _REENTRANT, asctime_r, and ctime_r, I
suggest getting a copy of the Posix.1c standard before committing to a
particular solution here.

More information about the tz mailing list