bostic@OKEEFFE.BERKELEY.EDU.UUCP (03/27/87)
The next four articles posted to comp.bugs.4bsd.ucb-fixes, ARTICLES #13 through #16, will concern the upcoming DST problem. They contain: ARTICLE #13 A minimal fix, hopefully easy to install. It contains fixes for both 4.2 and 4.3 BSD systems. To install this fix, unshar ARTICLE #13 in an empty directory and follow the instructions contained in the README file. ARTICLES #14, #15, #16 What Berkeley has installed. To install this fix, create a directory containing one other directory; the sub-directory should be called "tzone". Unshar ARTICLES #15 and #16 in this sub-directory. Unshar ARTICLE #14 in the top directory. Follow the instructions contained in the README file. You are reading ARTICLE #13. If you have any problems getting either package to work, please contact me. Keith Bostic bostic@ucbvax.berkeley.edu ucbvax!bostic seismo!keith +1 (415) 642-4948 ... cut here ... echo x - README sed 's/^X//' >README << 'END-of-README' XThis is the minimal set of fixes for the 1987 DST problem. It involves a Xchange to the C library and a single include file. The following files Xshould have been provided: X X README # the file you're reading X diff.ctime.c.4.2BSD # context diff with 4.2BSD for ctime.c X diff.ctime.c.4.3BSD # context diff with 4.3BSD for ctime.c X diff.time.h.4.2BSD # context diff with 4.2BSD for time.h X diff.time.h.4.3BSD # context diff with 4.3BSD for time.h X XThey should all be present as part of ARTICLE #13, as posted to Xcomp.bugs.4bsd.ucb-fixes. Note, ARTICLES #14, #15, and #16 are a Xmuch more comprehensive fix and are completely separate from this Xfix. X XTo install: X XStep #1: X Patch the following source with the indicated files: X X For 4.2BSD systems: X /usr/src/lib/libc/gen/ctime.c diff.ctime.c.4.2BSD X /sys/h/time.h diff.time.h.4.2BSD X X For 4.3BSD systems: X /usr/src/lib/libc/gen/ctime.c diff.ctime.c.4.3BSD X /sys/h/time.h diff.time.h.4.3BSD X XStep #2: X Rebuild and install all of your source. On 4.2BSD and 4.3BSD X systems, the simplest way is probably: X X "cd /usr/src/lib/libc;make;make install" X "cd /usr/src;make;make install" X X If you are unable to do this, rebuild and install the following X programs. This list reflects the dependencies for 4.3BSD X systems, so it may be somewhat incorrect for 4.2BSD sites. X Xsrc/bin adb, ar, date, diff, login, ls, mail, make, pr, ps, X su, tar, tp, wall, who, write Xsrc/etc XNSrouted, ac, arff, comsat, cron, dmesg, dump, dumpfs, X fsck, ftpd, getty, halt, implog, inetd, named, restore, X ntalkd, rdump, reboot, rlogind, routed, rrestore, rshd, X rwhod, savecore, shutdown, syslogd, talkd, telnetd, X tftpd, timed Xsrc/games adventure, battlestar, boggle, mille, monop, snake Xsrc/new X/xclock, ansi, apl, courier, dipress, emacs, help, X hyper, icon, jove, kermit, mh, mmdf, news, nntp, X notes, pup, rcs, sumacc Xsrc/old 512restor, berknet, dnd, dump.4.1, talk, vpr Xsrc/ucb Mail, dbx, ex, finger, fp, last, lastcomm, leave, X lisp, liszt, lock, logger, msgs, pascal, rdist, X rwho, script, sysline, systat, vgrind, vmstat, w Xsrc/undoc v6mail Xsrc/usr.bin ar11, at, calendar, efl usr.bin/xsend, find, learn, X refer, tip, uucp Xsrc/usr.lib libF77, libI77, libU77, libpc, lpr, sendmail END-of-README echo x - diff.ctime.c.4.2BSD sed 's/^X//' >diff.ctime.c.4.2BSD << 'END-of-diff.ctime.c.4.2BSD' X*** /arch/4.2bsd/usr/src/lib/libc/gen/ctime.c Sat Jul 9 14:03:55 1983 X--- ctime.c.new Tue Mar 24 07:27:04 1987 X*************** X*** 1,7 **** X- #ifndef lint X- static char sccsid[] = "@(#)ctime.c 4.4 (Berkeley) 7/9/83"; X- #endif X /* X * This routine converts time as follows. X * The epoch is 0000 Jan 1 1970 GMT. X * The argument time is in seconds since then. X--- 1,14 ---- X /* X+ * Copyright (c) 1980 Regents of the University of California. X+ * All rights reserved. The Berkeley software License Agreement X+ * specifies the terms and conditions for redistribution. X+ */ X+ X+ #if defined(LIBC_SCCS) && !defined(lint) X+ static char sccsid[] = "@(#)ctime.c 5.5 (Berkeley) 3/9/86"; X+ #endif LIBC_SCCS and not lint X+ X+ /* X * This routine converts time as follows. X * The epoch is 0000 Jan 1 1970 GMT. X * The argument time is in seconds since then. X*************** X*** 28,35 **** X * where tvec is produced by localtime X * returns a ptr to a character string X * that has the ascii time in the form X! * Thu Jan 01 00:00:00 1970n0\\ X! * 01234567890123456789012345 X * 0 1 2 X * X * ctime(t) just calls localtime, then asctime. X--- 35,42 ---- X * where tvec is produced by localtime X * returns a ptr to a character string X * that has the ascii time in the form X! * Thu Jan 01 00:00:00 1970\n\0 X! * 0123456789012345678901234 5 X * 0 1 2 X * X * ctime(t) just calls localtime, then asctime. X*************** X*** 57,65 **** X }; X X /* X! * The following table is used for 1974 and 1975 and X! * gives the day number of the first day after the Sunday of the X! * change. X */ X struct dstab { X int dayyr; X--- 64,86 ---- X }; X X /* X! * The following tables specify the days that daylight savings time X! * started and ended for some year or, if the year in the table is X! * 0, for all years not explicitly mentioned in the table. X! * Both days are assumed to be Sundays. For entries for specific years, X! * they are given as the day number of the Sunday of the change. For X! * wildcard entries, it is assumed that the day is specified by a rule X! * of the form "first Sunday of <some month>" or "last Sunday of <some X! * month>." In the former case, the negative of the day number of the X! * first day of that month is given; in the latter case, the day number X! * of the last day of that month is given. X! * X! * In the northern hemisphere, Daylight Savings Time runs for a period in X! * the middle of the year; thus, days between the start day and the end X! * day have DST active. In the southern hemisphere, Daylight Savings Time X! * runs from the beginning of the year to some time in the middle of the X! * year, and from some time later in the year to the end of the year; thus, X! * days after the start day or before the end day have DST active. X */ X struct dstab { X int dayyr; X*************** X*** 67,106 **** X int dayle; X }; X X static struct dstab usdaytab[] = { X! 1974, 5, 333, /* 1974: Jan 6 - last Sun. in Nov */ X! 1975, 58, 303, /* 1975: Last Sun. in Feb - last Sun in Oct */ X! 0, 119, 303, /* all other years: end Apr - end Oct */ X }; X static struct dstab ausdaytab[] = { X 1970, 400, 0, /* 1970: no daylight saving at all */ X! 1971, 303, 0, /* 1971: daylight saving from Oct 31 */ X! 1972, 303, 58, /* 1972: Jan 1 -> Feb 27 & Oct 31 -> dec 31 */ X! 0, 303, 65, /* others: -> Mar 7, Oct 31 -> */ X }; X X /* X! * The European tables ... based on hearsay X * Believed correct for: X! * WE: Great Britain, Ireland, Portugal X * ME: Belgium, Luxembourg, Netherlands, Denmark, Norway, X! * Austria, Poland, Czechoslovakia, Sweden, Switzerland, X! * DDR, DBR, France, Spain, Hungary, Italy, Jugoslavia X! * Eastern European dst is unknown, we'll make it ME until someone speaks up. X! * EE: Bulgaria, Finland, Greece, Rumania, Turkey, Western Russia X */ X! static struct dstab wedaytab[] = { X! 1983, 86, 303, /* 1983: end March - end Oct */ X! 1984, 86, 303, /* 1984: end March - end Oct */ X! 1985, 86, 303, /* 1985: end March - end Oct */ X! 0, 400, 0, /* others: no daylight saving at all ??? */ X }; X X! static struct dstab medaytab[] = { X! 1983, 86, 272, /* 1983: end March - end Sep */ X! 1984, 86, 272, /* 1984: end March - end Sep */ X! 1985, 86, 272, /* 1985: end March - end Sep */ X! 0, 400, 0, /* others: no daylight saving at all ??? */ X }; X X static struct dayrules { X--- 88,220 ---- X int dayle; X }; X X+ /* X+ * The U.S. tables, including the latest hack. X+ */ X static struct dstab usdaytab[] = { X! 1970, 119, 303, /* 1970: last Sun. in Apr - last Sun. in Oct */ X! 1971, 119, 303, /* 1971: last Sun. in Apr - last Sun. in Oct */ X! 1972, 119, 303, /* 1972: last Sun. in Apr - last Sun. in Oct */ X! 1973, 119, 303, /* 1973: last Sun. in Apr - last Sun. in Oct */ X! 1974, 5, 303, /* 1974: Jan 6 - last Sun. in Oct */ X! 1975, 58, 303, /* 1975: Last Sun. in Feb - last Sun. in Oct */ X! 1976, 119, 303, /* 1976: last Sun. in Apr - last Sun. in Oct */ X! 1977, 119, 303, /* 1977: last Sun. in Apr - last Sun. in Oct */ X! 1978, 119, 303, /* 1978: last Sun. in Apr - last Sun. in Oct */ X! 1979, 119, 303, /* 1979: last Sun. in Apr - last Sun. in Oct */ X! 1980, 119, 303, /* 1980: last Sun. in Apr - last Sun. in Oct */ X! 1981, 119, 303, /* 1981: last Sun. in Apr - last Sun. in Oct */ X! 1982, 119, 303, /* 1982: last Sun. in Apr - last Sun. in Oct */ X! 1983, 119, 303, /* 1983: last Sun. in Apr - last Sun. in Oct */ X! 1984, 119, 303, /* 1984: last Sun. in Apr - last Sun. in Oct */ X! 1985, 119, 303, /* 1985: last Sun. in Apr - last Sun. in Oct */ X! 1986, 119, 303, /* 1986: last Sun. in Apr - last Sun. in Oct */ X! 0, -90, 303, /* 1987 on: first Sun. in Apr - last Sun. in Oct */ X }; X+ X+ /* X+ * Canada, same as the US, except no early 70's fluctuations. X+ */ X+ static struct dstab candaytab[] = { X+ 1970, 119, 303, /* 1970: last Sun. in Apr - last Sun. in Oct */ X+ 1971, 119, 303, /* 1971: last Sun. in Apr - last Sun. in Oct */ X+ 1972, 119, 303, /* 1972: last Sun. in Apr - last Sun. in Oct */ X+ 1973, 119, 303, /* 1973: last Sun. in Apr - last Sun. in Oct */ X+ 1974, 119, 303, /* 1974: last Sun. in Apr - last Sun. in Oct */ X+ 1975, 119, 303, /* 1975: Last Sun. in Apr - last Sun. in Oct */ X+ 1976, 119, 303, /* 1976: last Sun. in Apr - last Sun. in Oct */ X+ 1977, 119, 303, /* 1977: last Sun. in Apr - last Sun. in Oct */ X+ 1978, 119, 303, /* 1978: last Sun. in Apr - last Sun. in Oct */ X+ 1979, 119, 303, /* 1979: last Sun. in Apr - last Sun. in Oct */ X+ 1980, 119, 303, /* 1980: last Sun. in Apr - last Sun. in Oct */ X+ 1981, 119, 303, /* 1981: last Sun. in Apr - last Sun. in Oct */ X+ 1982, 119, 303, /* 1982: last Sun. in Apr - last Sun. in Oct */ X+ 1983, 119, 303, /* 1983: last Sun. in Apr - last Sun. in Oct */ X+ 1984, 119, 303, /* 1984: last Sun. in Apr - last Sun. in Oct */ X+ 1985, 119, 303, /* 1985: last Sun. in Apr - last Sun. in Oct */ X+ 1986, 119, 303, /* 1986: last Sun. in Apr - last Sun. in Oct */ X+ 0, -90, 303, /* 1987 on: first Sun. in Apr - last Sun. in Oct */ X+ }; X+ X+ /* X+ * The Australian tables, for states with DST that don't shift the ending time X+ * starting in 1986, but shift it starting in 1987. X+ */ X static struct dstab ausdaytab[] = { X 1970, 400, 0, /* 1970: no daylight saving at all */ X! 1971, 303, 0, /* 1971: daylight saving from last Sun. in Oct */ X! 1972, 303, 57, /* 1972: Jan 1 -> Feb 27 & last Sun. in Oct -> Dec 31 */ X! 1973, 303, -59, /* 1973: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1974, 303, -59, /* 1974: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1975, 303, -59, /* 1975: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1976, 303, -59, /* 1976: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1977, 303, -59, /* 1977: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1978, 303, -59, /* 1978: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1979, 303, -59, /* 1979: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1980, 303, -59, /* 1980: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1981, 303, -59, /* 1981: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1982, 303, -59, /* 1982: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1983, 303, -59, /* 1983: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1984, 303, -59, /* 1984: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1985, 303, -59, /* 1985: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1986, -290, -59, /* 1986: -> first Sun. in Mar, first Sun. after Oct 17 -> */ X! 0, -290, 79, /* 1987 on: -> last Sun. before Mar 21, first Sun. after Oct 17 -> */ X }; X X /* X! * The Australian tables, for states with DST that do shift the ending time X! * starting in 1986. NSW does so; there seems to be a difference of opinion X! * about which other states do. There is also a variation in 1983, but X! * Robert Elz didn't have it at hand when last he reported. X! * Extending the 1986 shift on to infinity is Elz's best guess. X! */ X! static struct dstab ausaltdaytab[] = { X! 1970, 400, 0, /* 1970: no daylight saving at all */ X! 1971, 303, 0, /* 1971: daylight saving from last Sun. in Oct */ X! 1972, 303, 57, /* 1972: Jan 1 -> Feb 27 & last Sun. in Oct -> Dec 31 */ X! 1973, 303, -59, /* 1973: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1974, 303, -59, /* 1974: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1975, 303, -59, /* 1975: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1976, 303, -59, /* 1976: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1977, 303, -59, /* 1977: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1978, 303, -59, /* 1978: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1979, 303, -59, /* 1979: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1980, 303, -59, /* 1980: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1981, 303, -59, /* 1981: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1982, 303, -59, /* 1982: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1983, 303, -59, /* 1983: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1984, 303, -59, /* 1984: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1985, 303, -59, /* 1985: -> first Sun. in Mar, last Sun. in Oct -> */ X! 0, -290, 79, /* 1986 on: -> last Sun. before Mar 21, first Sun. after Oct 17 -> */ X! }; X! X! /* X! * The European tables, based on investigations by PTB, Braunschweig, FRG. X * Believed correct for: X! * GB: United Kingdom and Eire X! * WE: Portugal, Poland (in fact MET, following WE dst rules) X * ME: Belgium, Luxembourg, Netherlands, Denmark, Norway, X! * Austria, Czechoslovakia, Sweden, Switzerland, X! * FRG, GDR, France, Spain, Hungary, Italy, Yugoslavia, X! * Western USSR (in fact EET+1; following ME dst rules) X! * EE: Finland, Greece, Israel? X! * X! * Problematic cases are: X! * WE: Iceland (no dst) X! * EE: Rumania, Turkey (in fact timezone EET+1) X! * Terra incognita: X! * Albania (MET), Bulgaria (EET), Cyprus (EET) X! * X! * Years before 1986 are suspect (complicated changes caused X! * e.g. by enlargement of the European Community). X! * Years before 1983 are VERY suspect (sigh!). X */ X! static struct dstab gbdaytab[] = { /* GB and Eire */ X! 0, 89, 303, /* all years: last Sun. in March - last Sun. in Oct */ X }; X X! static struct dstab cedaytab[] = { /* Continental European */ X! 0, 89, 272, /* all years: last Sun. in March - last Sun. in Sep */ X }; X X static struct dayrules { X*************** X*** 108,119 **** X int dst_hrs; /* hours to add when dst on */ X struct dstab * dst_rules; /* one of the above */ X enum {STH,NTH} dst_hemi; /* southern, northern hemisphere */ X } dayrules [] = { X! DST_USA, 1, usdaytab, NTH, X! DST_AUST, 1, ausdaytab, STH, X! DST_WET, 1, wedaytab, NTH, X! DST_MET, 1, medaytab, NTH, X! DST_EET, 1, medaytab, NTH, /* XXX */ X -1, X }; X X--- 222,240 ---- X int dst_hrs; /* hours to add when dst on */ X struct dstab * dst_rules; /* one of the above */ X enum {STH,NTH} dst_hemi; /* southern, northern hemisphere */ X+ int dst_ontime; /* hour when DST turns on */ X+ int dst_offtime; /* hour when DST turns off */ X } dayrules [] = { X! DST_USA, 1, usdaytab, NTH, 2, 1, X! DST_CAN, 1, candaytab, NTH, 2, 1, X! DST_AUST, 1, ausdaytab, STH, 2, 2, X! DST_AUSTALT, 1, ausaltdaytab, STH, 2, 2, X! DST_GB, 1, gbdaytab, NTH, 1, 1, X! DST_WET, 1, cedaytab, NTH, 1, 1, X! DST_MET, 1, cedaytab, NTH, 2, 2, X! DST_EET, 1, cedaytab, NTH, 3, 3, X! DST_RUM, 1, cedaytab, NTH, 0, 0, X! DST_TUR, 1, cedaytab, NTH, 1, 0, X -1, X }; X X*************** X*** 126,132 **** X X char * X ctime(t) X! unsigned long *t; X { X return(asctime(localtime(t))); X } X--- 247,253 ---- X X char * X ctime(t) X! time_t *t; X { X return(asctime(localtime(t))); X } X*************** X*** 133,152 **** X X struct tm * X localtime(tim) X! unsigned long *tim; X { X register int dayno; X register struct tm *ct; X! register dalybeg, daylend; X register struct dayrules *dr; X register struct dstab *ds; X int year; X! unsigned long copyt; X struct timeval curtime; X! struct timezone zone; X X! gettimeofday(&curtime, &zone); X! copyt = *tim - (unsigned long)zone.tz_minuteswest*60; X ct = gmtime(©t); X dayno = ct->tm_yday; X for (dr = dayrules; dr->dst_type >= 0; dr++) X--- 254,277 ---- X X struct tm * X localtime(tim) X! time_t *tim; X { X register int dayno; X register struct tm *ct; X! register daylbegin, daylend; X register struct dayrules *dr; X register struct dstab *ds; X int year; X! time_t copyt; X struct timeval curtime; X! static struct timezone zone; X! static int init = 0; X X! if (!init) { X! gettimeofday(&curtime, &zone); X! init++; X! } X! copyt = *tim - (time_t)zone.tz_minuteswest*60; X ct = gmtime(©t); X dayno = ct->tm_yday; X for (dr = dayrules; dr->dst_type >= 0; dr++) X*************** X*** 157,178 **** X for (ds = dr->dst_rules; ds->dayyr; ds++) X if (ds->dayyr == year) X break; X! dalybeg = ds->daylb; /* first Sun after dst starts */ X! daylend = ds->dayle; /* first Sun after dst ends */ X! dalybeg = sunday(ct, dalybeg); X! daylend = sunday(ct, daylend); X switch (dr->dst_hemi) { X case NTH: X if (!( X! (dayno>dalybeg || (dayno==dalybeg && ct->tm_hour>=2)) && X! (dayno<daylend || (dayno==daylend && ct->tm_hour<1)) X )) X return(ct); X break; X case STH: X if (!( X! (dayno>dalybeg || (dayno==dalybeg && ct->tm_hour>=2)) || X! (dayno<daylend || (dayno==daylend && ct->tm_hour<2)) X )) X return(ct); X break; X--- 282,305 ---- X for (ds = dr->dst_rules; ds->dayyr; ds++) X if (ds->dayyr == year) X break; X! daylbegin = sunday(ct, ds->daylb); /* Sun on which dst starts */ X! daylend = sunday(ct, ds->dayle); /* Sun on which dst ends */ X switch (dr->dst_hemi) { X case NTH: X if (!( X! (dayno>daylbegin X! || (dayno==daylbegin && ct->tm_hour>=dr->dst_ontime)) && X! (dayno<daylend X! || (dayno==daylend && ct->tm_hour<dr->dst_offtime)) X )) X return(ct); X break; X case STH: X if (!( X! (dayno>daylbegin X! || (dayno==daylbegin && ct->tm_hour>=dr->dst_ontime)) || X! (dayno<daylend X! || (dayno==daylend && ct->tm_hour<dr->dst_offtime)) X )) X return(ct); X break; X*************** X*** 188,195 **** X X /* X * The argument is a 0-origin day number. X! * The value is the day number of the first X! * Sunday on or after the day. X */ X static X sunday(t, d) X--- 315,324 ---- X X /* X * The argument is a 0-origin day number. X! * The value is the day number of the last X! * Sunday on or before the day (if "d" is positive) X! * or of the first Sunday on or after the day (if "d" is X! * negative). X */ X static X sunday(t, d) X*************** X*** 196,212 **** X register struct tm *t; X register int d; X { X if (d >= 58) X d += dysize(t->tm_year) - 365; X! return(d - (d - t->tm_yday + t->tm_wday + 700) % 7); X } X X struct tm * X gmtime(tim) X! unsigned long *tim; X { X register int d0, d1; X! unsigned long hms, day; X register int *tp; X static struct tm xtime; X X--- 325,348 ---- X register struct tm *t; X register int d; X { X+ register int offset; /* 700 if before, -700 if after */ X+ X+ offset = 700; X+ if (d < 0) { X+ offset = -700; X+ d = -d; X+ } X if (d >= 58) X d += dysize(t->tm_year) - 365; X! return(d - (d - t->tm_yday + t->tm_wday + offset) % 7); X } X X struct tm * X gmtime(tim) X! time_t *tim; X { X register int d0, d1; X! long hms, day; X register int *tp; X static struct tm xtime; X X*************** X*** 233,242 **** X /* X * day is the day number. X * generate day of the week. X! * The addend is 4 mod 7 (1/1/1970 was Thursday) X */ X X! xtime.tm_wday = (day+7340036)%7; X X /* X * year number X--- 369,378 ---- X /* X * day is the day number. X * generate day of the week. X! * The addend is 4, because 1/1/1970 was Thursday. X */ X X! xtime.tm_wday = (day + 4)%7; X X /* X * year number X*************** X*** 289,295 **** X cp = ct_numb(cp, *--tp+100); X if (t->tm_year>=100) { X cp[1] = '2'; X! cp[2] = '0' + t->tm_year >= 200; X } X cp += 2; X cp = ct_numb(cp, t->tm_year+100); X--- 425,431 ---- X cp = ct_numb(cp, *--tp+100); X if (t->tm_year>=100) { X cp[1] = '2'; X! cp[2] = '0' + (t->tm_year-100) / 100; X } X cp += 2; X cp = ct_numb(cp, t->tm_year+100); END-of-diff.ctime.c.4.2BSD echo x - diff.ctime.c.4.3BSD sed 's/^X//' >diff.ctime.c.4.3BSD << 'END-of-diff.ctime.c.4.3BSD' X*** /nbsd/usr/src/lib/libc/gen/ctime.c Sun Mar 9 19:45:32 1986 X--- ctime.c.new Tue Mar 24 07:27:04 1987 X*************** X*** 64,72 **** X }; X X /* X! * The following table is used for 1974 and 1975 and X! * gives the day number of the first day after the Sunday of the X! * change. X */ X struct dstab { X int dayyr; X--- 64,86 ---- X }; X X /* X! * The following tables specify the days that daylight savings time X! * started and ended for some year or, if the year in the table is X! * 0, for all years not explicitly mentioned in the table. X! * Both days are assumed to be Sundays. For entries for specific years, X! * they are given as the day number of the Sunday of the change. For X! * wildcard entries, it is assumed that the day is specified by a rule X! * of the form "first Sunday of <some month>" or "last Sunday of <some X! * month>." In the former case, the negative of the day number of the X! * first day of that month is given; in the latter case, the day number X! * of the last day of that month is given. X! * X! * In the northern hemisphere, Daylight Savings Time runs for a period in X! * the middle of the year; thus, days between the start day and the end X! * day have DST active. In the southern hemisphere, Daylight Savings Time X! * runs from the beginning of the year to some time in the middle of the X! * year, and from some time later in the year to the end of the year; thus, X! * days after the start day or before the end day have DST active. X */ X struct dstab { X int dayyr; X*************** X*** 74,135 **** X int dayle; X }; X X static struct dstab usdaytab[] = { X! 1974, 5, 333, /* 1974: Jan 6 - last Sun. in Nov */ X! 1975, 58, 303, /* 1975: Last Sun. in Feb - last Sun in Oct */ X! 0, 119, 303, /* all other years: end Apr - end Oct */ X }; X static struct dstab ausdaytab[] = { X 1970, 400, 0, /* 1970: no daylight saving at all */ X! 1971, 303, 0, /* 1971: daylight saving from Oct 31 */ X! 1972, 303, 58, /* 1972: Jan 1 -> Feb 27 & Oct 31 -> dec 31 */ X! 0, 303, 65, /* others: -> Mar 7, Oct 31 -> */ X }; X X /* X! * The European tables ... based on hearsay X * Believed correct for: X! * WE: Great Britain, Portugal? X * ME: Belgium, Luxembourg, Netherlands, Denmark, Norway, X! * Austria, Poland, Czechoslovakia, Sweden, Switzerland, X! * DDR, DBR, France, Spain, Hungary, Italy, Jugoslavia X! * Finland (EE timezone, but ME dst rules) X! * Eastern European dst is unknown, we'll make it ME until someone speaks up. X! * EE: Bulgaria, Greece, Rumania, Turkey, Western Russia X * X! * Ireland is unpredictable. (Years when Easter Sunday just happens ...) X! * Years before 1983 are suspect. X */ X! static struct dstab wedaytab[] = { X! 1983, 89, 296, /* 1983: end March - end Oct */ X! 0, 89, 303, /* others: end March - end Oct */ X }; X X! static struct dstab medaytab[] = { X! 1983, 89, 296, /* 1983: end March - end Oct */ X! 0, 89, 272, /* others: end March - end Sep */ X }; X X- /* X- * Canada, same as the US, except no early 70's fluctuations. X- * Can this really be right ?? X- */ X- static struct dstab candaytab[] = { X- 0, 119, 303, /* all years: end Apr - end Oct */ X- }; X- X static struct dayrules { X int dst_type; /* number obtained from system */ X int dst_hrs; /* hours to add when dst on */ X struct dstab * dst_rules; /* one of the above */ X enum {STH,NTH} dst_hemi; /* southern, northern hemisphere */ X } dayrules [] = { X! DST_USA, 1, usdaytab, NTH, X! DST_AUST, 1, ausdaytab, STH, X! DST_WET, 1, wedaytab, NTH, X! DST_MET, 1, medaytab, NTH, X! DST_EET, 1, medaytab, NTH, /* XXX */ X! DST_CAN, 1, candaytab, NTH, X -1, X }; X X--- 88,240 ---- X int dayle; X }; X X+ /* X+ * The U.S. tables, including the latest hack. X+ */ X static struct dstab usdaytab[] = { X! 1970, 119, 303, /* 1970: last Sun. in Apr - last Sun. in Oct */ X! 1971, 119, 303, /* 1971: last Sun. in Apr - last Sun. in Oct */ X! 1972, 119, 303, /* 1972: last Sun. in Apr - last Sun. in Oct */ X! 1973, 119, 303, /* 1973: last Sun. in Apr - last Sun. in Oct */ X! 1974, 5, 303, /* 1974: Jan 6 - last Sun. in Oct */ X! 1975, 58, 303, /* 1975: Last Sun. in Feb - last Sun. in Oct */ X! 1976, 119, 303, /* 1976: last Sun. in Apr - last Sun. in Oct */ X! 1977, 119, 303, /* 1977: last Sun. in Apr - last Sun. in Oct */ X! 1978, 119, 303, /* 1978: last Sun. in Apr - last Sun. in Oct */ X! 1979, 119, 303, /* 1979: last Sun. in Apr - last Sun. in Oct */ X! 1980, 119, 303, /* 1980: last Sun. in Apr - last Sun. in Oct */ X! 1981, 119, 303, /* 1981: last Sun. in Apr - last Sun. in Oct */ X! 1982, 119, 303, /* 1982: last Sun. in Apr - last Sun. in Oct */ X! 1983, 119, 303, /* 1983: last Sun. in Apr - last Sun. in Oct */ X! 1984, 119, 303, /* 1984: last Sun. in Apr - last Sun. in Oct */ X! 1985, 119, 303, /* 1985: last Sun. in Apr - last Sun. in Oct */ X! 1986, 119, 303, /* 1986: last Sun. in Apr - last Sun. in Oct */ X! 0, -90, 303, /* 1987 on: first Sun. in Apr - last Sun. in Oct */ X }; X+ X+ /* X+ * Canada, same as the US, except no early 70's fluctuations. X+ */ X+ static struct dstab candaytab[] = { X+ 1970, 119, 303, /* 1970: last Sun. in Apr - last Sun. in Oct */ X+ 1971, 119, 303, /* 1971: last Sun. in Apr - last Sun. in Oct */ X+ 1972, 119, 303, /* 1972: last Sun. in Apr - last Sun. in Oct */ X+ 1973, 119, 303, /* 1973: last Sun. in Apr - last Sun. in Oct */ X+ 1974, 119, 303, /* 1974: last Sun. in Apr - last Sun. in Oct */ X+ 1975, 119, 303, /* 1975: Last Sun. in Apr - last Sun. in Oct */ X+ 1976, 119, 303, /* 1976: last Sun. in Apr - last Sun. in Oct */ X+ 1977, 119, 303, /* 1977: last Sun. in Apr - last Sun. in Oct */ X+ 1978, 119, 303, /* 1978: last Sun. in Apr - last Sun. in Oct */ X+ 1979, 119, 303, /* 1979: last Sun. in Apr - last Sun. in Oct */ X+ 1980, 119, 303, /* 1980: last Sun. in Apr - last Sun. in Oct */ X+ 1981, 119, 303, /* 1981: last Sun. in Apr - last Sun. in Oct */ X+ 1982, 119, 303, /* 1982: last Sun. in Apr - last Sun. in Oct */ X+ 1983, 119, 303, /* 1983: last Sun. in Apr - last Sun. in Oct */ X+ 1984, 119, 303, /* 1984: last Sun. in Apr - last Sun. in Oct */ X+ 1985, 119, 303, /* 1985: last Sun. in Apr - last Sun. in Oct */ X+ 1986, 119, 303, /* 1986: last Sun. in Apr - last Sun. in Oct */ X+ 0, -90, 303, /* 1987 on: first Sun. in Apr - last Sun. in Oct */ X+ }; X+ X+ /* X+ * The Australian tables, for states with DST that don't shift the ending time X+ * starting in 1986, but shift it starting in 1987. X+ */ X static struct dstab ausdaytab[] = { X 1970, 400, 0, /* 1970: no daylight saving at all */ X! 1971, 303, 0, /* 1971: daylight saving from last Sun. in Oct */ X! 1972, 303, 57, /* 1972: Jan 1 -> Feb 27 & last Sun. in Oct -> Dec 31 */ X! 1973, 303, -59, /* 1973: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1974, 303, -59, /* 1974: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1975, 303, -59, /* 1975: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1976, 303, -59, /* 1976: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1977, 303, -59, /* 1977: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1978, 303, -59, /* 1978: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1979, 303, -59, /* 1979: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1980, 303, -59, /* 1980: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1981, 303, -59, /* 1981: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1982, 303, -59, /* 1982: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1983, 303, -59, /* 1983: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1984, 303, -59, /* 1984: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1985, 303, -59, /* 1985: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1986, -290, -59, /* 1986: -> first Sun. in Mar, first Sun. after Oct 17 -> */ X! 0, -290, 79, /* 1987 on: -> last Sun. before Mar 21, first Sun. after Oct 17 -> */ X }; X X /* X! * The Australian tables, for states with DST that do shift the ending time X! * starting in 1986. NSW does so; there seems to be a difference of opinion X! * about which other states do. There is also a variation in 1983, but X! * Robert Elz didn't have it at hand when last he reported. X! * Extending the 1986 shift on to infinity is Elz's best guess. X! */ X! static struct dstab ausaltdaytab[] = { X! 1970, 400, 0, /* 1970: no daylight saving at all */ X! 1971, 303, 0, /* 1971: daylight saving from last Sun. in Oct */ X! 1972, 303, 57, /* 1972: Jan 1 -> Feb 27 & last Sun. in Oct -> Dec 31 */ X! 1973, 303, -59, /* 1973: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1974, 303, -59, /* 1974: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1975, 303, -59, /* 1975: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1976, 303, -59, /* 1976: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1977, 303, -59, /* 1977: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1978, 303, -59, /* 1978: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1979, 303, -59, /* 1979: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1980, 303, -59, /* 1980: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1981, 303, -59, /* 1981: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1982, 303, -59, /* 1982: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1983, 303, -59, /* 1983: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1984, 303, -59, /* 1984: -> first Sun. in Mar, last Sun. in Oct -> */ X! 1985, 303, -59, /* 1985: -> first Sun. in Mar, last Sun. in Oct -> */ X! 0, -290, 79, /* 1986 on: -> last Sun. before Mar 21, first Sun. after Oct 17 -> */ X! }; X! X! /* X! * The European tables, based on investigations by PTB, Braunschweig, FRG. X * Believed correct for: X! * GB: United Kingdom and Eire X! * WE: Portugal, Poland (in fact MET, following WE dst rules) X * ME: Belgium, Luxembourg, Netherlands, Denmark, Norway, X! * Austria, Czechoslovakia, Sweden, Switzerland, X! * FRG, GDR, France, Spain, Hungary, Italy, Yugoslavia, X! * Western USSR (in fact EET+1; following ME dst rules) X! * EE: Finland, Greece, Israel? X * X! * Problematic cases are: X! * WE: Iceland (no dst) X! * EE: Rumania, Turkey (in fact timezone EET+1) X! * Terra incognita: X! * Albania (MET), Bulgaria (EET), Cyprus (EET) X! * X! * Years before 1986 are suspect (complicated changes caused X! * e.g. by enlargement of the European Community). X! * Years before 1983 are VERY suspect (sigh!). X */ X! static struct dstab gbdaytab[] = { /* GB and Eire */ X! 0, 89, 303, /* all years: last Sun. in March - last Sun. in Oct */ X }; X X! static struct dstab cedaytab[] = { /* Continental European */ X! 0, 89, 272, /* all years: last Sun. in March - last Sun. in Sep */ X }; X X static struct dayrules { X int dst_type; /* number obtained from system */ X int dst_hrs; /* hours to add when dst on */ X struct dstab * dst_rules; /* one of the above */ X enum {STH,NTH} dst_hemi; /* southern, northern hemisphere */ X+ int dst_ontime; /* hour when DST turns on */ X+ int dst_offtime; /* hour when DST turns off */ X } dayrules [] = { X! DST_USA, 1, usdaytab, NTH, 2, 1, X! DST_CAN, 1, candaytab, NTH, 2, 1, X! DST_AUST, 1, ausdaytab, STH, 2, 2, X! DST_AUSTALT, 1, ausaltdaytab, STH, 2, 2, X! DST_GB, 1, gbdaytab, NTH, 1, 1, X! DST_WET, 1, cedaytab, NTH, 1, 1, X! DST_MET, 1, cedaytab, NTH, 2, 2, X! DST_EET, 1, cedaytab, NTH, 3, 3, X! DST_RUM, 1, cedaytab, NTH, 0, 0, X! DST_TUR, 1, cedaytab, NTH, 1, 0, X -1, X }; X X*************** X*** 153,159 **** X { X register int dayno; X register struct tm *ct; X! register dalybeg, daylend; X register struct dayrules *dr; X register struct dstab *ds; X int year; X--- 258,264 ---- X { X register int dayno; X register struct tm *ct; X! register daylbegin, daylend; X register struct dayrules *dr; X register struct dstab *ds; X int year; X*************** X*** 177,198 **** X for (ds = dr->dst_rules; ds->dayyr; ds++) X if (ds->dayyr == year) X break; X! dalybeg = ds->daylb; /* first Sun after dst starts */ X! daylend = ds->dayle; /* first Sun after dst ends */ X! dalybeg = sunday(ct, dalybeg); X! daylend = sunday(ct, daylend); X switch (dr->dst_hemi) { X case NTH: X if (!( X! (dayno>dalybeg || (dayno==dalybeg && ct->tm_hour>=2)) && X! (dayno<daylend || (dayno==daylend && ct->tm_hour<1)) X )) X return(ct); X break; X case STH: X if (!( X! (dayno>dalybeg || (dayno==dalybeg && ct->tm_hour>=2)) || X! (dayno<daylend || (dayno==daylend && ct->tm_hour<2)) X )) X return(ct); X break; X--- 282,305 ---- X for (ds = dr->dst_rules; ds->dayyr; ds++) X if (ds->dayyr == year) X break; X! daylbegin = sunday(ct, ds->daylb); /* Sun on which dst starts */ X! daylend = sunday(ct, ds->dayle); /* Sun on which dst ends */ X switch (dr->dst_hemi) { X case NTH: X if (!( X! (dayno>daylbegin X! || (dayno==daylbegin && ct->tm_hour>=dr->dst_ontime)) && X! (dayno<daylend X! || (dayno==daylend && ct->tm_hour<dr->dst_offtime)) X )) X return(ct); X break; X case STH: X if (!( X! (dayno>daylbegin X! || (dayno==daylbegin && ct->tm_hour>=dr->dst_ontime)) || X! (dayno<daylend X! || (dayno==daylend && ct->tm_hour<dr->dst_offtime)) X )) X return(ct); X break; X*************** X*** 209,215 **** X /* X * The argument is a 0-origin day number. X * The value is the day number of the last X! * Sunday on or before the day. X */ X static X sunday(t, d) X--- 316,324 ---- X /* X * The argument is a 0-origin day number. X * The value is the day number of the last X! * Sunday on or before the day (if "d" is positive) X! * or of the first Sunday on or after the day (if "d" is X! * negative). X */ X static X sunday(t, d) X*************** X*** 216,224 **** X register struct tm *t; X register int d; X { X if (d >= 58) X d += dysize(t->tm_year) - 365; X! return(d - (d - t->tm_yday + t->tm_wday + 700) % 7); X } X X struct tm * X--- 325,340 ---- X register struct tm *t; X register int d; X { X+ register int offset; /* 700 if before, -700 if after */ X+ X+ offset = 700; X+ if (d < 0) { X+ offset = -700; X+ d = -d; X+ } X if (d >= 58) X d += dysize(t->tm_year) - 365; X! return(d - (d - t->tm_yday + t->tm_wday + offset) % 7); X } X X struct tm * X*************** X*** 253,262 **** X /* X * day is the day number. X * generate day of the week. X! * The addend is 4 mod 7 (1/1/1970 was Thursday) X */ X X! xtime.tm_wday = (day+7340036)%7; X X /* X * year number X--- 369,378 ---- X /* X * day is the day number. X * generate day of the week. X! * The addend is 4, because 1/1/1970 was Thursday. X */ X X! xtime.tm_wday = (day + 4)%7; X X /* X * year number END-of-diff.ctime.c.4.3BSD echo x - diff.time.h.4.2BSD sed 's/^X//' >diff.time.h.4.2BSD << 'END-of-diff.time.h.4.2BSD' X*** /arch/4.2bsd/sys/h/time.h Fri Jul 29 06:49:21 1983 X--- /tmp/4.2bsd.new.time.h Tue Mar 24 07:57:36 1987 X*************** X*** 19,24 **** X--- 19,29 ---- X #define DST_WET 3 /* Western European dst */ X #define DST_MET 4 /* Middle European dst */ X #define DST_EET 5 /* Eastern European dst */ X+ #define DST_CAN 6 /* Canada */ X+ #define DST_GB 7 /* Great Britain and Eire */ X+ #define DST_RUM 8 /* Rumania */ X+ #define DST_TUR 9 /* Turkey */ X+ #define DST_AUSTALT 10 /* Australian style with shift in 1986 */ X X /* X * Operations on timevals. END-of-diff.time.h.4.2BSD echo x - diff.time.h.4.3BSD sed 's/^X//' >diff.time.h.4.3BSD << 'END-of-diff.time.h.4.3BSD' X*** /nbsd/sys/h/time.h Wed Jun 4 23:29:26 1986 X--- time.h.new Tue Mar 24 07:27:04 1987 X*************** X*** 6,11 **** X--- 6,14 ---- X * @(#)time.h 7.1 (Berkeley) 6/4/86 X */ X X+ #ifndef _TIME_ X+ #define _TIME_ X+ X /* X * Structure returned by gettimeofday(2) system call, X * and used in other calls. X*************** X*** 26,31 **** X--- 29,38 ---- X #define DST_MET 4 /* Middle European dst */ X #define DST_EET 5 /* Eastern European dst */ X #define DST_CAN 6 /* Canada */ X+ #define DST_GB 7 /* Great Britain and Eire */ X+ #define DST_RUM 8 /* Rumania */ X+ #define DST_TUR 9 /* Turkey */ X+ #define DST_AUSTALT 10 /* Australian style with shift in 1986 */ X X /* X * Operations on timevals. X*************** X*** 54,56 **** X--- 61,65 ---- X #ifndef KERNEL X #include <time.h> X #endif X+ X+ #endif !_TIME_ END-of-diff.time.h.4.3BSD exit