I briefly looked for a fix for the problem that Dave Sparks reported today with zic.c, and decided that this will require more zic expertise than I have. However, I did find a couple of related bugs in zic.c by code inspection. First, there are a couple of places in the code that compare for equality to min_year, but values less than min_year are possible if -s is given, so these should be changed to compare for not greater than min_year. (While we're at it, we might as well make max_year symmetric.) Second, the setboundaries function sets min_year and max_year based on GMT, but these values are meant to be bounds for localtime years, so to be safe one must subtract 1 from the GMT min year and add 1 to the GMT max year. This is particularly important with the -s option, since the GMT min year is 1970 but the localtime min year might be 1969. Here is a proposed patch. This patch doesn't fix Sparks's bug, unfortunately. 1997-03-02 Paul Eggert <eggert@twinsun.com> * zic.c (setboundaries): Set min_year to be one less than GMT min_year, and max_year to be one greater than GMT max_year, in case local time and GMT disagree about years at time boundaries. (outzone, tadd): Don't assume that min_time and max_time are bounds on time_t values, since -s makes this assumption false. =================================================================== RCS file: RCS/zic.c,v retrieving revision 1997.2.1.1 retrieving revision 1997.2.1.2 diff -c -r1997.2.1.1 -r1997.2.1.2 *** zic.c 1997/02/28 00:22:22 1997.2.1.1 --- zic.c 1997/03/03 03:58:26 1997.2.1.2 *************** *** 647,654 **** max_time <<= TIME_T_BITS_IN_FILE - 1; --max_time; } ! min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year; ! max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year; } static int --- 647,654 ---- max_time <<= TIME_T_BITS_IN_FILE - 1; --max_time; } ! min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year - 1; ! max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year + 1; } static int *************** *** 1638,1645 **** if (!rp->r_todisstd) offset = oadd(offset, stdoff); jtime = rp->r_temp; ! if (jtime == min_time || ! jtime == max_time) continue; jtime = tadd(jtime, -offset); if (k < 0 || jtime < ktime) { --- 1638,1645 ---- if (!rp->r_todisstd) offset = oadd(offset, stdoff); jtime = rp->r_temp; ! if (jtime <= min_time || ! jtime >= max_time) continue; jtime = tadd(jtime, -offset); if (k < 0 || jtime < ktime) { *************** *** 1978,1986 **** { register time_t t; ! if (t1 == max_time && t2 > 0) return max_time; ! if (t1 == min_time && t2 < 0) return min_time; t = t1 + t2; if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { --- 1978,1986 ---- { register time_t t; ! if (t1 >= max_time && t2 > 0) return max_time; ! if (t1 <= min_time && t2 < 0) return min_time; t = t1 + t2; if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) {