Strftime's %C and %y formats versus wide-ranging tm_year values

Paul Eggert eggert at CS.UCLA.EDU
Mon Oct 18 21:18:22 UTC 2004


"Olson, Arthur David (NIH/NCI)" <olsona at dc37a.nci.nih.gov> writes:

> Yet another iteration on wide-ranging tm_year values; as usual, the diffs
> below are against the stuff in ftp://elsie.nci.nih.gov/pub at the moment.

That looks good; thanks.  Two (no, make it three) points.  First, the
strftime.c implementation of _yconv still has a bug in that it runs
off the end of the function without a return statement.  Second, there
should be a comment in asctime.c noting the disagreement with the
formal standards.  Third (and least important) asctime_r could be
recoded to avoid a strcpy in the common case when asctime invokes
asctime_r.  Here's a proposed patch.

===================================================================
RCS file: RCS/strftime.c,v
retrieving revision 2004.4.1.3
retrieving revision 2004.4.0.6
diff -pu -r2004.4.1.3 -r2004.4.0.6
--- strftime.c	2004/10/18 16:24:42	2004.4.1.3
+++ strftime.c	2004/10/18 21:08:04	2004.4.0.6
@@ -635,6 +635,8 @@ const char * const	ptlim;
 	}
 	if (convert_yy)
 		pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim);
+
+	return pt;
 }
 
 #ifdef LOCALE_HOME
===================================================================
RCS file: RCS/asctime.c,v
retrieving revision 2004.3.1.4
retrieving revision 2004.3.0.6
diff -pu -r2004.3.1.4 -r2004.3.0.6
--- asctime.c	2004/10/18 16:24:42	2004.3.1.4
+++ asctime.c	2004/10/18 21:07:37	2004.3.0.6
@@ -28,6 +28,8 @@ static char	elsieid[] = "@(#)asctime.c	7
 ** leading zeroes to get the newline in the traditional place.
 ** The -4 ensures that we get four characters of output even if
 ** we call a strftime variant that produces fewer characters for some years.
+** The ISO C 1999 and POSIX 1003.1-2004 standards prohibit padding the year,
+** but many implementations pad anyway; most likely the standards are buggy.
 */
 #define ASCTIME_FMT	"%.3s %.3s%3d %02.2d:%02.2d:%02.2d %-4s\n"
 /*
@@ -90,13 +92,15 @@ char *				buf;
 	/*
 	** We avoid using snprintf since it's not available on all systems.
 	*/
-	(void) sprintf(result, 
+	(void) sprintf(buf == buf_asctime ? buf : result,
 		((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B),
 		wn, mn,
 		timeptr->tm_mday, timeptr->tm_hour,
 		timeptr->tm_min, timeptr->tm_sec,
 		year);
-	if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime) {
+	if (buf == buf_asctime)
+		return buf;
+	else if (strlen(result) < STD_ASCTIME_BUF_SIZE) {
 		(void) strcpy(buf, result);
 		return buf;
 	} else {



More information about the tz mailing list