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