[tz] NetBSD and Android bionic APIs for tz values
Paul Eggert
eggert at cs.ucla.edu
Mon Aug 25 07:32:47 UTC 2014
Paul Eggert wrote:
> A preliminary proposed patch to NetBSD-current sources attached.
Following up on this, I implemented it for tzcode; see
http://mm.icann.org/pipermail/tz/2014-August/021516.html
In doing so it struck me that the proposal for new functions tm_strftime
and tm_strftime_l is overkill, and that it's better to simply fix
strftime and strftime_l to do the right thing with %z and %Z, as that's
what glibc does. I understand there's an argument that POSIX doesn't
allow this behavior, but it's not clear to me that the argument is
correct, and anyway NetBSD would be in good company when it's compatible
with tzcode and with GNU/Linux here. So attached is a a revised patch
that simply removes strftime_z/strftime_lz and fixes
strftime/strftime_l. The rest of the patch is the same as before.
-------------- next part --------------
Index: libc/compat/include/time.h
===================================================================
RCS file: /cvsroot/src/lib/libc/compat/include/time.h,v
retrieving revision 1.3
diff -u -b -w -r1.3 time.h
--- libc/compat/include/time.h 16 Dec 2010 18:38:06 -0000 1.3
+++ libc/compat/include/time.h 25 Aug 2014 07:22:52 -0000
@@ -92,15 +92,12 @@
int32_t timeoff(struct tm *, long);
int32_t time2posix(int32_t);
int32_t posix2time(int32_t);
-struct tm *localtime_rz(const timezone_t, const int32_t * __restrict,
+struct tm *localtime_rz(timezone_t __restrict, const int32_t * __restrict,
struct tm * __restrict);
-char *ctime_rz(const timezone_t, const int32_t *, char *);
-int32_t mktime_z(const timezone_t, struct tm *);
-int32_t timelocal_z(const timezone_t, struct tm *);
-int32_t time2posix_z(const timezone_t, int32_t);
-int32_t posix2time_z(const timezone_t, int32_t);
+int32_t mktime_z(timezone_t __restrict, struct tm * __restrict);
+int32_t time2posix_z(timezone_t, int32_t);
+int32_t posix2time_z(timezone_t, int32_t);
timezone_t tzalloc(const char *);
-void tzfree(const timezone_t);
-const char *tzgetname(const timezone_t, int);
+void tzfree(timezone_t);
#endif /* !_COMPAT_TIME_H_ */
Index: libc/compat/time/compat_localtime.c
===================================================================
RCS file: /cvsroot/src/lib/libc/compat/time/compat_localtime.c,v
retrieving revision 1.3
diff -u -b -w -r1.3 compat_localtime.c
--- libc/compat/time/compat_localtime.c 21 Feb 2011 22:07:44 -0000 1.3
+++ libc/compat/time/compat_localtime.c 25 Aug 2014 07:22:52 -0000
@@ -16,7 +16,6 @@
#ifdef __weak_alias
__weak_alias(ctime_r,_ctime_r)
-__weak_alias(ctime_rz,_ctime_rz)
__weak_alias(gmtime_r,_gmtime_r)
__weak_alias(localtime_r,_localtime_r)
__weak_alias(localtime_rz,_localtime_rz)
@@ -35,9 +34,6 @@
__warn_references(ctime_r,
"warning: reference to compatibility ctime_r();"
" include <time.h> for correct reference")
-__warn_references(ctime_rz,
- "warning: reference to compatibility ctime_rz();"
- " include <time.h> for correct reference")
__warn_references(gmtime_r,
"warning: reference to compatibility gmtime_r();"
" include <time.h> for correct reference")
Index: libc/include/namespace.h
===================================================================
RCS file: /cvsroot/src/lib/libc/include/namespace.h,v
retrieving revision 1.174
diff -u -b -w -r1.174 namespace.h
--- libc/include/namespace.h 13 Jun 2014 15:45:05 -0000 1.174
+++ libc/include/namespace.h 25 Aug 2014 07:22:52 -0000
@@ -244,7 +244,6 @@
#define csetexpandtc _csetexpandtc
#define ctermid _ctermid
#define ctime_r _ctime_r
-#define ctime_rz _ctime_rz
#define daemon _daemon
#define dbopen _dbopen
#define devname _devname
@@ -629,8 +628,6 @@
#define strdup _strdup
#define stresep _stresep
#define strftime_l _strftime_l
-#define strftime_lz _strftime_lz
-#define strftime_z _strftime_z
#define strndup _strndup
#define strncasecmp _strncasecmp
#define strptime _strptime
Index: libc/time/Makefile.inc
===================================================================
RCS file: /cvsroot/src/lib/libc/time/Makefile.inc,v
retrieving revision 1.18
diff -u -b -w -r1.18 Makefile.inc
--- libc/time/Makefile.inc 16 Jan 2014 20:31:43 -0000 1.18
+++ libc/time/Makefile.inc 25 Aug 2014 07:22:52 -0000
@@ -8,7 +8,6 @@
CPPFLAGS+=-DALL_STATE -DUSG_COMPAT
MLINKS+=ctime.3 ctime_r.3 \
- ctime.3 ctime_rz.3 \
ctime.3 asctime.3 \
ctime.3 asctime_r.3 \
ctime.3 difftime.3 \
@@ -21,7 +20,6 @@
ctime.3 mktime_z.3 \
ctime.3 tzalloc.3 \
ctime.3 tzfree.3 \
- ctime.3 tzgetname.3 \
getdate.3 getdate_err.3 \
offtime.3 offtime_r.3 \
offtime.3 timeoff.3 \
@@ -31,7 +29,6 @@
time2posix.3 posix2time_z.3 \
time2posix.3 time2posix_z.3 \
tzset.3 daylight.3 \
- tzset.3 tzsetwall.3 \
- strftime.3 strftime_z.3
+ tzset.3 tzsetwall.3
COPTS.strftime.c = -Wno-format-nonliteral
Index: libc/time/ctime.3
===================================================================
RCS file: /cvsroot/src/lib/libc/time/ctime.3,v
retrieving revision 1.50
diff -u -b -w -r1.50 ctime.3
--- libc/time/ctime.3 15 Aug 2014 11:04:07 -0000 1.50
+++ libc/time/ctime.3 25 Aug 2014 07:22:52 -0000
@@ -10,7 +10,6 @@
.Nm asctime_r ,
.Nm ctime ,
.Nm ctime_r ,
-.Nm ctime_rz ,
.Nm difftime ,
.Nm gmtime ,
.Nm gmtime_r ,
@@ -20,7 +19,6 @@
.Nm mktime ,
.Nm mktime_z ,
.Nm tzalloc ,
-.Nm tzgetname ,
.Nm tzfree ,
.Nd convert date and time
.Sh LIBRARY
@@ -36,8 +34,6 @@
.Fn ctime "const time_t *clock"
.Ft char *
.Fn ctime_r "const time_t *clock" "char *buf"
-.Ft char *
-.Fn ctime_rz "const timezone_t tz" "const time_t *clock" "char *buf"
.Ft double
.Fn difftime "time_t time1" "time_t time0"
.Ft struct tm *
@@ -49,17 +45,16 @@
.Ft struct tm *
.Fn localtime_r "const time_t * restrict clock" "struct tm * restrict result"
.Ft struct tm *
-.Fn localtime_rz "const timezone_t tz" "const time_t * restrict clock" "struct tm * restrict result"
+.Fn localtime_rz "timezone_t restrict tz" "const time_t * restrict clock" "struct tm * restrict result"
.Ft time_t
.Fn mktime "struct tm *tm"
.Ft time_t
-.Fn mktime_z "const timezone_t tz" "struct tm *tm"
+.Fn mktime_z "timezone_t restrict tz" "struct tm * restrict tm"
.Ft timezone_t
.Fn tzalloc "const char *zone"
.Ft void
-.Fn tzfree "const timezone_t tz"
+.Fn tzfree "timezone_t tz"
.Ft const char *
-.Fn tzgetname "const timezone_t tz" "int isdst"
.Sh DESCRIPTION
The
.Nm
@@ -127,18 +122,6 @@
.Fa buf
argument, which should be 26 or more bytes long,
instead of using a global static buffer.
-.It Fn ctime_rz "tz" "clock" "buf"
-The
-.Fn ctime_rz
-function is similar to
-.Fn ctime_r ,
-but it also takes a
-.Ft "const timezone_t"
-argument, as returned by a previous call to
-.Fn tzalloc ,
-or a null pointer denoting
-Coordinated Universal Time
-.Pq Tn UTC .
.It Fn difftime "time1" "time2"
The
.Fn difftime
@@ -200,7 +183,7 @@
function is similar to
.Fn localtime_r ,
but it also takes a
-.Ft "const timezone_t"
+.Ft timezone_t
argument, returned by a previous call to
.Fn tzalloc ,
or a null pointer denoting
@@ -280,7 +263,7 @@
function is similar to
.Fn mktime
but it also takes a
-.Ft "const timezone_t"
+.Ft timezone_t
argument, returned by a previous call to
.Fn tzalloc ,
or a null pointer denoting
@@ -292,8 +275,7 @@
function takes as an argument a timezone name and returns a
.Ft timezone_t
object suitable to be used in the
-.Fn ctime_rz ,
-.Fn localtime_rz ,
+.Fn localtime_rz
and
.Fn mktime_z
functions.
@@ -321,23 +303,6 @@
.Fa tz ,
which was previously allocated by
.Fn tzalloc .
-.It Fn "tzgetname"
-Finally,
-.Fn tzgetname
-returns the name for the given
-.Fa tz .
-If
-.Fa isdst
-is
-.Va 0 ,
-the call is equivalent to
-.Va tzname[0] .
-If
-.Fa isdst
-is set to
-.Va 1
-the call is equivalent to
-.Va tzname[1] .
.El
.Pp
Declarations of all the functions and externals, and the
@@ -389,11 +354,10 @@
and
.Fn ctime
functions return a pointer to a static character buffer, and the
-.Fn asctime_r ,
-.Fn ctime_r ,
+.Fn asctime_r
and
-.Fn ctime_rz
-function return a pointer to the user-supplied buffer.
+.Fn ctime_r
+functions return a pointer to the user-supplied buffer.
On failure they all return
.Dv NULL
and no errors are defined for them.
Index: libc/time/localtime.c
===================================================================
RCS file: /cvsroot/src/lib/libc/time/localtime.c,v
retrieving revision 1.85
diff -u -b -w -r1.85 localtime.c
--- libc/time/localtime.c 16 Aug 2014 16:22:21 -0000 1.85
+++ libc/time/localtime.c 25 Aug 2014 07:22:52 -0000
@@ -286,19 +286,6 @@
return result;
}
-const char *
-tzgetname(const timezone_t sp, int isdst)
-{
- int i;
- for (i = 0; i < sp->timecnt; ++i) {
- const struct ttinfo *const ttisp = &sp->ttis[sp->types[i]];
-
- if (ttisp->tt_isdst == isdst)
- return &sp->chars[ttisp->tt_abbrind];
- }
- return NULL;
-}
-
static void
settzname_z(timezone_t sp)
{
@@ -1728,17 +1715,6 @@
return asctime_r(rtm, buf);
}
-char *
-ctime_rz(const timezone_t sp, const time_t * timep, char *buf)
-{
- struct tm mytm, *rtm;
-
- rtm = localtime_rz(sp, timep, &mytm);
- if (rtm == NULL)
- return NULL;
- return asctime_r(rtm, buf);
-}
-
/*
** Adapted from code provided by Robert Elz, who writes:
** The "best" way to do mktime I think is based on an idea of Bob
@@ -2158,14 +2134,6 @@
#ifdef STD_INSPIRED
time_t
-timelocal_z(const timezone_t sp, struct tm *const tmp)
-{
- if (tmp != NULL)
- tmp->tm_isdst = -1; /* in case it wasn't initialized */
- return mktime_z(sp, tmp);
-}
-
-time_t
timelocal(struct tm *const tmp)
{
if (tmp != NULL)
Index: libc/time/strftime.3
===================================================================
RCS file: /cvsroot/src/lib/libc/time/strftime.3,v
retrieving revision 1.30
diff -u -b -w -r1.30 strftime.3
--- libc/time/strftime.3 20 Sep 2013 19:06:54 -0000 1.30
+++ libc/time/strftime.3 25 Aug 2014 07:22:52 -0000
@@ -36,8 +36,7 @@
.Dt STRFTIME 3
.Os
.Sh NAME
-.Nm strftime ,
-.Nm strftime_z
+.Nm strftime
.Nd format date and time
.Sh LIBRARY
.Lb libc
@@ -45,8 +44,6 @@
.In time.h
.Ft size_t
.Fn strftime "char * restrict buf" "size_t maxsize" "const char * restrict format" "const struct tm * restrict timeptr"
-.Ft size_t
-.Fn strftime_z "const timezone_t tz" "char * restrict buf" "size_t maxsize" "const char * restrict format" "const struct tm * restrict timeptr"
.Sh DESCRIPTION
The
.Fn strftime
@@ -199,15 +196,6 @@
is replaced by
.Ql % .
.El
-.Pp
-The
-.Fn strftime_z
-function is similar to
-.Fn strftime ,
-but it also takes a
-.Ft "const timezone_t"
-.Fa tz
-argument.
.Sh SEE ALSO
.Xr date 1 ,
.Xr printf 1 ,
Index: libc/time/strftime.c
===================================================================
RCS file: /cvsroot/src/lib/libc/time/strftime.c,v
retrieving revision 1.31
diff -u -b -w -r1.31 strftime.c
--- libc/time/strftime.c 15 Aug 2014 11:04:07 -0000 1.31
+++ libc/time/strftime.c 25 Aug 2014 07:22:52 -0000
@@ -27,17 +27,6 @@
#include "private.h"
/*
-** We don't use these extensions in strftime operation even when
-** supported by the local tzcode configuration. A strictly
-** conforming C application may leave them in undefined state.
-*/
-
-#ifdef _LIBC
-#undef TM_ZONE
-#undef TM_GMTOFF
-#endif
-
-/*
** Copyright (c) 1989, 1993
** The Regents of the University of California. All rights reserved.
**
@@ -76,8 +65,6 @@
#ifdef __weak_alias
__weak_alias(strftime_l, _strftime_l)
-__weak_alias(strftime_lz, _strftime_lz)
-__weak_alias(strftime_z, _strftime_z)
#endif
#include "sys/localedef.h"
@@ -87,7 +74,7 @@
static char * _add(const char *, char *, const char *);
static char * _conv(int, const char *, char *, const char *);
-static char * _fmt(const timezone_t, const char *, const struct tm *, char *,
+static char * _fmt(const char *, const struct tm *, char *,
const char *, int *, locale_t);
static char * _yconv(int, int, int, int, char *, const char *);
@@ -103,21 +90,14 @@
#define IN_ALL 3
size_t
-strftime_z(const timezone_t sp, char * __restrict s, size_t maxsize,
- const char * __restrict format, const struct tm * __restrict t)
-{
- return strftime_lz(sp, s, maxsize, format, t, _current_locale());
-}
-
-size_t
-strftime_lz(const timezone_t sp, char *const s, const size_t maxsize,
- const char *const format, const struct tm *const t, locale_t loc)
+strftime_l(char * __restrict s, size_t maxsize, const char * __restrict format,
+ const struct tm * __restrict t, locale_t loc)
{
char * p;
int warn;
warn = IN_NONE;
- p = _fmt(sp, ((format == NULL) ? "%c" : format), t, s, s + maxsize,
+ p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize,
&warn, loc);
#ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) {
@@ -142,7 +122,7 @@
}
static char *
-_fmt(const timezone_t sp, const char *format, const struct tm *const t,
+_fmt(const char *format, const struct tm *const t,
char *pt, const char *const ptlim, int *warnp, locale_t loc)
{
for ( ; *format; ++format) {
@@ -192,7 +172,7 @@
{
int warn2 = IN_SOME;
- pt = _fmt(sp, _TIME_LOCALE(loc)->c_fmt, t, pt,
+ pt = _fmt(_TIME_LOCALE(loc)->c_fmt, t, pt,
ptlim, &warn2, loc);
if (warn2 == IN_ALL)
warn2 = IN_THIS;
@@ -201,7 +181,7 @@
}
continue;
case 'D':
- pt = _fmt(sp, "%m/%d/%y", t, pt, ptlim, warnp,
+ pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp,
loc);
continue;
case 'd':
@@ -223,7 +203,7 @@
pt = _conv(t->tm_mday, "%2d", pt, ptlim);
continue;
case 'F':
- pt = _fmt(sp, "%Y-%m-%d", t, pt, ptlim, warnp,
+ pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp,
loc);
continue;
case 'H':
@@ -288,11 +268,11 @@
pt, ptlim);
continue;
case 'R':
- pt = _fmt(sp, "%H:%M", t, pt, ptlim, warnp,
+ pt = _fmt("%H:%M", t, pt, ptlim, warnp,
loc);
continue;
case 'r':
- pt = _fmt(sp, _TIME_LOCALE(loc)->t_fmt_ampm, t,
+ pt = _fmt(_TIME_LOCALE(loc)->t_fmt_ampm, t,
pt, ptlim, warnp, loc);
continue;
case 'S':
@@ -317,7 +297,7 @@
}
continue;
case 'T':
- pt = _fmt(sp, "%H:%M:%S", t, pt, ptlim, warnp,
+ pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp,
loc);
continue;
case 't':
@@ -433,7 +413,7 @@
** "date as dd-bbb-YYYY"
** (ado, 1993-05-24)
*/
- pt = _fmt(sp, "%e-%b-%Y", t, pt, ptlim, warnp,
+ pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp,
loc);
continue;
case 'W':
@@ -447,14 +427,14 @@
pt = _conv(t->tm_wday, "%d", pt, ptlim);
continue;
case 'X':
- pt = _fmt(sp, _TIME_LOCALE(loc)->t_fmt, t, pt,
+ pt = _fmt(_TIME_LOCALE(loc)->t_fmt, t, pt,
ptlim, warnp, loc);
continue;
case 'x':
{
int warn2 = IN_SOME;
- pt = _fmt(sp, _TIME_LOCALE(loc)->d_fmt, t, pt,
+ pt = _fmt(_TIME_LOCALE(loc)->d_fmt, t, pt,
ptlim, &warn2, loc);
if (warn2 == IN_ALL)
warn2 = IN_THIS;
@@ -472,94 +452,14 @@
pt, ptlim);
continue;
case 'Z':
-#ifdef TM_ZONE
- if (t->TM_ZONE != NULL)
- pt = _add(t->TM_ZONE, pt, ptlim);
- else
-#endif /* defined TM_ZONE */
- if (t->tm_isdst >= 0)
- pt = _add((sp ?
- tzgetname(sp, t->tm_isdst) :
- tzname[t->tm_isdst != 0]),
- pt, ptlim);
- /*
- ** C99 says that %Z must be replaced by the
- ** empty string if the time zone is not
- ** determinable.
- */
+ pt = _add(t->tm_zone, pt, ptlim);
continue;
case 'z':
{
long diff;
char const * sign;
- if (t->tm_isdst < 0)
- continue;
-#ifdef TM_GMTOFF
- diff = (int)t->TM_GMTOFF;
-#else /* !defined TM_GMTOFF */
- /*
- ** C99 says that the UT offset must
- ** be computed by looking only at
- ** tm_isdst. This requirement is
- ** incorrect, since it means the code
- ** must rely on magic (in this case
- ** altzone and timezone), and the
- ** magic might not have the correct
- ** offset. Doing things correctly is
- ** tricky and requires disobeying C99;
- ** see GNU C strftime for details.
- ** For now, punt and conform to the
- ** standard, even though it's incorrect.
- **
- ** C99 says that %z must be replaced by the
- ** empty string if the time zone is not
- ** determinable, so output nothing if the
- ** appropriate variables are not available.
- */
-#ifndef STD_INSPIRED
- if (t->tm_isdst == 0)
-#ifdef USG_COMPAT
- diff = -timezone;
-#else /* !defined USG_COMPAT */
- continue;
-#endif /* !defined USG_COMPAT */
- else
-#ifdef ALTZONE
- diff = -altzone;
-#else /* !defined ALTZONE */
- continue;
-#endif /* !defined ALTZONE */
-#else /* defined STD_INSPIRED */
- {
- struct tm tmp;
- time_t lct, gct;
-
- /*
- ** Get calendar time from t
- ** being treated as local.
- */
- tmp = *t; /* mktime discards const */
- lct = mktime(&tmp);
-
- if (lct == (time_t)-1)
- continue;
-
- /*
- ** Get calendar time from t
- ** being treated as GMT.
- **/
- tmp = *t; /* mktime discards const */
- gct = timegm(&tmp);
-
- if (gct == (time_t)-1)
- continue;
-
- /* LINTED difference will fit int */
- diff = (intmax_t)gct - (intmax_t)lct;
- }
-#endif /* defined STD_INSPIRED */
-#endif /* !defined TM_GMTOFF */
+ diff = t->tm_gmtoff;
if (diff < 0) {
sign = "-";
diff = -diff;
@@ -574,7 +474,7 @@
continue;
#if 0
case '+':
- pt = _fmt(sp, _TIME_LOCALE(loc)->date_fmt, t,
+ pt = _fmt(_TIME_LOCALE(loc)->date_fmt, t,
pt, ptlim, warnp, loc);
continue;
#endif
@@ -599,16 +499,7 @@
strftime(char * const s, const size_t maxsize,
const char * const format, const struct tm * const t)
{
- tzset();
- return strftime_z(NULL, s, maxsize, format, t);
-}
-
-size_t
-strftime_l(char * __restrict s, size_t maxsize, const char * __restrict format,
- const struct tm * __restrict t, locale_t loc)
-{
- tzset();
- return strftime_lz(NULL, s, maxsize, format, t, loc);
+ return strftime_l(s, maxsize, format, t, _current_locale());
}
static char *
Index: libc/time/time2posix.3
===================================================================
RCS file: /cvsroot/src/lib/libc/time/time2posix.3,v
retrieving revision 1.18
diff -u -b -w -r1.18 time2posix.3
--- libc/time/time2posix.3 15 Aug 2014 11:04:07 -0000 1.18
+++ libc/time/time2posix.3 25 Aug 2014 07:22:52 -0000
@@ -15,11 +15,11 @@
.Ft time_t
.Fn time2posix "time_t t"
.Ft time_t
-.Fn time2posix_z "const timezone_t tz" "time_t t"
+.Fn time2posix_z "timezone_t tz" "time_t t"
.Ft time_t
.Fn posix2time "time_t t"
.Ft time_t
-.Fn posix2time_z "const timezone_t tz" "time_t t"
+.Fn posix2time_z "timezone_t tz" "time_t t"
.Sh DESCRIPTION
.St -p1003.1
legislates that a
More information about the tz
mailing list