"Olson, Arthur David (NIH/NCI)" <olsona@dc37a.nci.nih.gov> writes:
Below are proposed asctime-related changes to the time zone package
Thanks. I compiled and tested them and have a couple of thoughts. First, GCC warns about zdump.c's new signed-versus-unsigned comparisons "timeptr->tm_wday >= sizeof ...." and similarly for tm_mon. The comparisons aren't needed here, since the values are guaranteed to be in range, so the easiest fix is to remove them. Second, it'd be nice if the asctime/ctime documentation explains more of the stuff we've discussed recently. Here are proposed further patches along these lines: they assume the patches you just sent. =================================================================== RCS file: RCS/newctime.3,v retrieving revision 2004.2.1.1 retrieving revision 2004.2.1.1.0.1 diff -pu -r2004.2.1.1 -r2004.2.1.1.0.1 --- newctime.3 2004/08/05 16:04:29 2004.2.1.1 +++ newctime.3 2004/08/05 19:20:33 2004.2.1.1.0.1 @@ -45,8 +45,12 @@ string of the form .eo Thu Nov 24 18:22:48 1986\n\0 .br -.ce .ec +where \en and \e0 represent a newline and null character, respectively. +Years requiring fewer than four characters are padded with +trailing spaces. +The year before the year 1 is the year 0, the year before that is +the year \-1, and so forth. For years longer than four characters, the string is of the form .br .ce @@ -54,8 +58,11 @@ For years longer than four characters, t Thu Nov 24 18:22:48 81986\n\0 .ec .br +with five spaces before the year. This unusual format is designed to +make it less likely that older software that expects exactly 26 bytes +of output will mistakenly output misleading values for out-of-range years. .PP -.IR Localtime\^ +.I Localtime\^ and .I gmtime\^ return pointers to ``tm'' structures, described below. @@ -213,6 +220,20 @@ will also be overwritten at the next cal (and by calls to .IR tzset ). .PP +.I Asctime\^ +and +.I ctime\^ +behave strangely for years before 1000 or after 9999. +The 1989 and 1999 editions of the C Standard say +that years from \-99 through 999 are converted without +extra spaces, but this conflicts with longstanding +tradition and with this implementation. +Traditional implementations of these two functions are +restricted to years in the range 1900 through 2099. +To avoid this portability mess, new programs should use +.I strftime\^ +instead. +.PP Avoid using out-of-range values with .I mktime when setting up lunch with promptness sticklers in Riyadh. =================================================================== RCS file: RCS/zdump.c,v retrieving revision 2004.2.1.1 retrieving revision 2004.2.1.1.0.1 diff -pu -r2004.2.1.1 -r2004.2.1.1.0.1 --- zdump.c 2004/08/05 16:04:29 2004.2.1.1 +++ zdump.c 2004/08/05 19:19:36 2004.2.1.1.0.1 @@ -378,26 +378,9 @@ static void dumptime(timeptr) register const struct tm * timeptr; { - static const char wday_name[][3] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - }; - static const char mon_name[][3] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; - register const char * wn; - register const char * mn; - - if (timeptr->tm_wday < 0 || - timeptr->tm_wday >= sizeof wday_name / sizeof wday_name[0]) - wn = "???"; - else wn = wday_name[timeptr->tm_wday]; - if (timeptr->tm_mon < 0 || - timeptr->tm_mon >= sizeof mon_name / sizeof mon_name[0]) - mn = "???"; - else mn = mon_name[timeptr->tm_mon]; (void) printf("%.3s %.3s%3d %.2d:%.2d:%.2d %ld", - wn, mn, + "SunMonTueWedThuFriSat" + 3 * timeptr->tm_wday, + "JanFebMarAprMayJunJulAugSepOctNovDec" + 3 * timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec, timeptr->tm_year + (long) TM_YEAR_BASE);