The proposed strftime.c code for the %C conversion uses _lconv, but the converted value can't possibly fall outside the range INT_MIN..INT_MAX so it might be a bit more efficient to use _conv. The %C conversion expression "(t->tm_year + (long) TM_YEAR_BASE) / 100" returns the wrong result in some cases due to overflow, e.g., if t->tm_year == INT_MAX and INT_MAX==LONG_MAX. It looks like you've leaning towards having %y generate year%100 even when the year is negative, but I'd like to present a new arguemnt for generating year mod 100 instead, on the grounds of preventing buffer overruns in older code. Most programmers expect strftime %y to generate exactly two digits, in the range 00-99 as the the C Standard explicitly requires. Generating strings like "-1" or (especially) "-99" might cause errors (e.g., buffer overruns) in older code. The situation for %g is similar. %C is less straightforward, since here the C Standard requires the impossible (it says the output range must be 00-99). However, I'd argue that it's least surprising if %C is consistent with %y, i.e., if %C is (year - (year mod 100)) / 100. The following proposed patch addresses the above issues. =================================================================== RCS file: RCS/strftime.c,v retrieving revision 2001.4.1.1 retrieving revision 2001.4.0.2 diff -pu -r2001.4.1.1 -r2001.4.0.2 --- strftime.c 2004/09/07 12:21:29 2001.4.1.1 +++ strftime.c 2004/09/07 19:11:35 2001.4.0.2 @@ -211,9 +211,12 @@ label: ** something completely different. ** (ado, 1993-05-24) */ - pt = _lconv((t->tm_year + - (long) TM_YEAR_BASE) / 100, - "%02ld", pt, ptlim); + { + int c = (TM_YEAR_BASE / 100 + + t->tm_year / 100 + - (t->tm_year % 100 < 0)); + pt = _conv(c, "%02d", pt, ptlim); + } continue; case 'c': { @@ -439,9 +442,12 @@ label: pt = _conv(w, "%02d", pt, ptlim); else if (*format == 'g') { + int g = year % 100; + if (g < 0) + g += 100; *warnp = IN_ALL; - pt = _conv(int(year % 100), - "%02d", pt, ptlim); + pt = _conv(g, "%02d", + pt, ptlim); } else pt = _lconv(year, "%04ld", pt, ptlim); } @@ -479,11 +485,13 @@ label: } continue; case 'y': + { + int y = t->tm_year % 100; + if (y < 0) + y += 100; *warnp = IN_ALL; - pt = _conv( - (int) ((t->tm_year + - (long) TM_YEAR_BASE) % 100), - "%02d", pt, ptlim); + pt = _conv(y, "%02d", pt, ptlim); + } continue; case 'Y': pt = _lconv(t->tm_year + (long) TM_YEAR_BASE,