The new C Standard specifies two new formats for strftime: %F and %z. Here's a proposed patch to add support for this. I ran into a Solaris 8 porting problem when debugging this, and enclose a patch for this as well. =================================================================== RCS file: RCS/Makefile,v retrieving revision 2000.1 retrieving revision 2000.1.0.1 diff -pu -r2000.1 -r2000.1.0.1 --- Makefile 2000/01/18 14:21:10 2000.1 +++ Makefile 2000/04/13 19:11:13 2000.1.0.1 @@ -88,6 +88,8 @@ LDLIBS= # Add the following to the end of the "CFLAGS=" line as needed. # -DHAVE_ADJTIME=0 if `adjtime' does not exist (SVR0?) # -DHAVE_GETTEXT=1 if `gettext' works (GNU, Linux, Solaris); also see LDLIBS +# -DHAVE_INCOMPATIBLE_CTIME_R=1 if your system's time.h declares +# ctime_r and asctime_r incompatibly with the POSIX standard. # -DHAVE_LONG_DOUBLE=1 if your compiler supports the `long double' type # -DHAVE_SETTIMEOFDAY=0 if settimeofday does not exist (SVR0?) # -DHAVE_SETTIMEOFDAY=1 if settimeofday has just 1 arg (SVR4) =================================================================== RCS file: RCS/private.h,v retrieving revision 1999.5 retrieving revision 1999.5.0.1 diff -pu -r1999.5 -r1999.5.0.1 --- private.h 1999/08/17 18:09:09 1999.5 +++ private.h 2000/04/13 19:11:13 1999.5.0.1 @@ -38,6 +38,10 @@ static char privatehid[] = "@(#)private. #define HAVE_GETTEXT 0 #endif /* !defined HAVE_GETTEXT */ +#ifndef HAVE_INCOMPATIBLE_CTIME_R +#define HAVE_INCOMPATIBLE_CTIME_R 1 +#endif /* !defined INCOMPATIBLE_CTIME_R */ + #ifndef HAVE_SETTIMEOFDAY #define HAVE_SETTIMEOFDAY 3 #endif /* !defined HAVE_SETTIMEOFDAY */ @@ -66,6 +70,11 @@ static char privatehid[] = "@(#)private. #define LOCALE_HOME "/usr/lib/locale" #endif /* !defined LOCALE_HOME */ +#if HAVE_INCOMPATIBLE_CTIME_R +#define asctime_r _incompatible_asctime_r +#define ctime_r _incompatible_ctime_r +#endif /* HAVE_INCOMPATIBLE_CTIME_R */ + /* ** Nested includes */ @@ -203,6 +212,28 @@ void icfree P((char * pointer)); void ifree P((char * pointer)); char * scheck P((const char *string, const char *format)); +/* +** External declarations, possibly renamed to private identifiers. +*/ +#ifndef USG_COMPAT +#define timezone _timezone +#define daylight _daylight +#endif +#ifndef ALTZONE +#define altzone _altzone +#endif +/* strftime needs these variables if TM_GMTOFF is not defined. */ +#ifndef TM_GMTOFF +#define USG_COMPAT +#define ALTZONE +#endif +#ifdef USG_COMPAT +extern time_t timezone; +extern int daylight; +#endif +#ifdef ALTZONE +extern time_t altzone; +#endif /* ** Finally, some convenience items. @@ -277,6 +308,13 @@ char * scheck P((const char *string, con #define TZ_DOMAIN "tz" #endif /* !defined TZ_DOMAIN */ +#if HAVE_INCOMPATIBLE_CTIME_R +#undef asctime_r +#undef ctime_r +char *asctime_r P((struct tm const *, char *)); +char *ctime_r P((time_t const *, char *)); +#endif /* HAVE_INCOMPATIBLE_CTIME_R */ + /* ** UNIX was a registered trademark of UNIX System Laboratories in 1993. */ =================================================================== RCS file: RCS/strftime.c,v retrieving revision 1999.9 retrieving revision 1999.9.0.1 diff -pu -r1999.9 -r1999.9.0.1 --- strftime.c 1999/11/08 19:54:36 1999.9 +++ strftime.c 2000/04/13 19:11:13 1999.9.0.1 @@ -247,6 +247,9 @@ label: case 'e': pt = _conv(t->tm_mday, "%2d", pt, ptlim); continue; + case 'F': + pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp); + continue; case 'H': pt = _conv(t->tm_hour, "%02d", pt, ptlim); continue; @@ -489,10 +492,46 @@ label: pt = _add(t->TM_ZONE, pt, ptlim); else #endif /* defined TM_ZONE */ - if (t->tm_isdst == 0 || t->tm_isdst == 1) { - pt = _add(tzname[t->tm_isdst], + if (0 <= t->tm_isdst) + pt = _add(tzname[t->tm_isdst != 0], pt, ptlim); - } else pt = _add("?", pt, ptlim); + continue; + case 'z': + { + int diff; + char const *sign; + if (t->tm_isdst < 0) + continue; +#ifdef TM_GMTOFF + diff = t->TM_GMTOFF; +#else /* !defined TM_GMTOFF */ + /* + ** C99 says that the UTC 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. + ** + */ + diff = - (t->tm_isdst ? altzone : timezone); +#endif /* !defined TM_GMTOFF */ + if (diff < 0) { + sign = "-"; + diff = -diff; + } else + sign = "+"; + pt = _add(sign, pt, ptlim); + diff /= 60; + pt = _conv((diff/60)*100 + diff%60, + "%04d", pt, ptlim); + } continue; case '+': pt = _fmt(Locale->date_fmt, t, pt, ptlim,