[comp.bugs.misc] diffs for ctime.c for new DST rules, v7 systems

dave@lsuc.UUCP (David Sherman) (02/08/87)

(Note: this is cross-posted to several groups to increase its
chances of being seen by those who will want it. Followups are
directed to comp.bugs.misc.)

Both the U.S. and Canada (well, Ontario and at least some of the
other provinces) are adopting the new daylight savings time rules,
switching to DST the first Sunday in April instead of the last,
beginning in 1987.  Below is a diff for /usr/src/libc/gen/ctime.c
for v7 systems; if you're running v7 you should be able to feed
this article right into "patch".

Once you make the change to ctime.c, anything which calls
ctime(3), localtime(3) or getdate(3) should be recompiled.
I've gone through the source on our system, and found all
the commands that call these routines.
To be absolutely correct for the future, all of these should be
recompiled after the ctime change is installed.  Some of the
requirements are pretty minor, however; things like adb and awk
use ctime for diagnotic purposes only, I believe.

Here are the commands I'll be changing.  This is under Perkin-Elmer
Edition VII Workbench.  Other systems will differ; grep for
getdate, localtime and cdate through your source files.

/usr/src/cmd (basic v7 stuff):
make adb tp xsend spool/lpd awk learn uucp/* tar refer mail
ac at atrun calendar cron date ar find info iostat login ls
pr prof sa who write

/usr/src/ucb (stuff which came from Berkeley):
ex/exrecover snake daytime tod finger script ucbmail

/usr/sys/cmd (v7 and Berkeley stuff which is hardware-specific):
dmesg dump dumpdir fsck restor restor512 w

/usr/src/local (stuff off the net, etc.):
clock hdate logacct type whopast notes diff cpio news month
dumpdates last lastdown lastlog logcount lu talloc msgs

Now, to the ctime.c diffs:

The changed file will have #define NorthAm but not USA, which is
correct for Canada. If you are in the USA, add #define USA as well.
(The 1974-75 change didn't apply in Canada.)

(I also put in a minor speedup posted to the net a while back;
the test of year==74||year==75 is changed to year<=75&&year>=74,
which it a bit faster for dates between 1975 and 1987.)

Thanks to Mark Brader, {lsuc,sq}!msb, for the DST changes.
*** ctime.c.old	Thu Mar  6 19:58:52 1986
--- ctime.c	Sat Feb  7 21:13:55 1987
***************
*** 1,4
! #define	USA
  /*
  #define	Australia
  */

--- 1,4 -----
! #define	NorthAm	/* North America */
  /*
  #define	USA
  #define	Australia
***************
*** 1,5
  #define	USA
  /*
  #define	Australia
  */
  

--- 1,6 -----
  #define	NorthAm	/* North America */
  /*
+ #define	USA
  #define	Australia
  */
  
***************
*** 26,31
   *
   * The routine calls the system to determine the local
   * timezone and whether Daylight Saving Time is permitted locally.
  #ifdef	USA
   * (DST is then determined by the current US standard rules)
   * There is a table that accounts for the peculiarities

--- 27,34 -----
   *
   * The routine calls the system to determine the local
   * timezone and whether Daylight Saving Time is permitted locally.
+ #ifdef	NorthAm
+  * (DST is then determined by the current US and Canadian standard rules)
  #ifdef	USA
   * There is a table that accounts for the peculiarities
   * undergone by daylight time in 1974-1975.
***************
*** 27,33
   * The routine calls the system to determine the local
   * timezone and whether Daylight Saving Time is permitted locally.
  #ifdef	USA
-  * (DST is then determined by the current US standard rules)
   * There is a table that accounts for the peculiarities
   * undergone by daylight time in 1974-1975.
  #endif

--- 30,35 -----
  #ifdef	NorthAm
   * (DST is then determined by the current US and Canadian standard rules)
  #ifdef	USA
   * There is a table that accounts for the peculiarities
   * undergone by daylight time in 1974-1975.
  #endif
***************
*** 31,36
   * There is a table that accounts for the peculiarities
   * undergone by daylight time in 1974-1975.
  #endif
  #ifdef	Australia
   * (DST is then determined according to the Summer Time Act 1973 (Vic))
  #endif

--- 33,39 -----
   * There is a table that accounts for the peculiarities
   * undergone by daylight time in 1974-1975.
  #endif
+ #endif
  #ifdef	Australia
   * (DST is then determined according to the Summer Time Act 1973 (Vic))
  #endif
***************
*** 61,67
  #define	DS_GAP	1	/* DS time difference is 1 hour */
  
  #endif
! #ifdef	USA
  	/*
  	 * daylight saving rules (copied from Bell original)
  	 */

--- 64,70 -----
  #define	DS_GAP	1	/* DS time difference is 1 hour */
  
  #endif
! #ifdef	NorthAm
  	/*
  	 * daylight saving rules (copied from Bell original)
  	 */
***************
*** 66,72
  	 * daylight saving rules (copied from Bell original)
  	 */
  #define	HEMI	&&	/* northern hemisphere */
! #define	DS_BEGIN 119	/* last possible start for DS, (last day in Apr) */
  #define	DS_END	303	/* last possible end day for DS, (last day in Oct) */
  #define	HOUR_ON	2	/* 2am - 3am is lost when DS starts */
  #define	HOUR_OFF 1	/* 1am - 2am runs twice when DS ends (??) */

--- 69,77 -----
  	 * daylight saving rules (copied from Bell original)
  	 */
  #define	HEMI	&&	/* northern hemisphere */
! #define	DS_BEGIN 119	/* old last possible start for DS, (last day in Apr) */
! #define	DS_NBEGIN 96	/* new last possible start for DS, (Apr 7) */
! 			/* (new rule begins in 1987) */
  #define	DS_END	303	/* last possible end day for DS, (last day in Oct) */
  #define	HOUR_ON	2	/* 2am - 3am is lost when DS starts */
  #define	HOUR_OFF 1	/* 1am - 2am runs twice when DS ends (??) */
***************
*** 140,145
  	dayno = ct->tm_yday;
  	daylbegin = DS_BEGIN;
  	daylend = DS_END;
  #ifdef	USA
  	if (ct->tm_year==74 || ct->tm_year==75) {
  		daylbegin = daytab[ct->tm_year-74].daylb;

--- 145,152 -----
  	dayno = ct->tm_yday;
  	daylbegin = DS_BEGIN;
  	daylend = DS_END;
+ #ifdef	NorthAm
+ 	if (ct->tm_year >= 87) daylbegin = DS_NBEGIN;
  #ifdef	USA
  	else if (ct->tm_year<=75 && ct->tm_year>=74) {
  		daylbegin = daytab[ct->tm_year-74].daylb;
***************
*** 141,147
  	daylbegin = DS_BEGIN;
  	daylend = DS_END;
  #ifdef	USA
! 	if (ct->tm_year==74 || ct->tm_year==75) {
  		daylbegin = daytab[ct->tm_year-74].daylb;
  		daylend = daytab[ct->tm_year-74].dayle;
  	}

--- 148,154 -----
  #ifdef	NorthAm
  	if (ct->tm_year >= 87) daylbegin = DS_NBEGIN;
  #ifdef	USA
! 	else if (ct->tm_year<=75 && ct->tm_year>=74) {
  		daylbegin = daytab[ct->tm_year-74].daylb;
  		daylend = daytab[ct->tm_year-74].dayle;
  	}
***************
*** 145,150
  		daylbegin = daytab[ct->tm_year-74].daylb;
  		daylend = daytab[ct->tm_year-74].dayle;
  	}
  #endif
  	daylbegin = sunday(ct, daylbegin);
  	daylend = sunday(ct, daylend);

--- 152,158 -----
  		daylbegin = daytab[ct->tm_year-74].daylb;
  		daylend = daytab[ct->tm_year-74].dayle;
  	}
+ #endif
  #endif
  	daylbegin = sunday(ct, daylbegin);
  	daylend = sunday(ct, daylend);

David Sherman
The Law Society of Upper Canada
Toronto
-- 
{ seismo!mnetor  cbosgd!utcs  watmath  decvax!utcsri  ihnp4!utzoo  } !lsuc!dave

edward@ukecc.UUCP (02/09/87)

In article <1565@lsuc.UUCP> dave@lsuc.UUCP (David Sherman) writes:
>Both the U.S. and Canada (well, Ontario and at least some of the
>other provinces) are adopting the new daylight savings time rules,
>switching to DST the first Sunday in April instead of the last,
>beginning in 1987.  Below is a diff for /usr/src/libc/gen/ctime.c
>for v7 systems; if you're running v7 you should be able to feed
>this article right into "patch".

I think we've all seen this coming, but shouldn't the writers of our
respective flavors of UNIX be providing the fixes. I'm not knocking
David's good intentions, but the DST switch can be viewed as a MAJOR
software bug worthy of an OFFICIAL update.

Guess it's time to call AT&T...

-- 
Edward C. Bennett			UUCP: cbosgd!ukma!ukecc!edward
					CSNET: edward@engr.uky.csnet
"Goodnight M.A."			BITNET: edward@ukma.BITNET
		Change the world. Make a new friend today.

jgy@hropus.UUCP (02/10/87)

> Now, to the ctime.c diffs:
> 
> The changed file will have #define NorthAm but not USA, which is
> correct for Canada. If you are in the USA, add #define USA as well.
> (The 1974-75 change didn't apply in Canada.)
> 
> (I also put in a minor speedup posted to the net a while back;
> the test of year==74||year==75 is changed to year<=75&&year>=74,
> which it a bit faster for dates between 1975 and 1987.)
> 

If you really want a speed-up make the call to 'tzset' in localtime()
dependent on a static variable not being initialized, this provides
some time savings for things like long "ls"'s etc..

guy@gorodish.UUCP (02/10/87)

>I think we've all seen this coming, but shouldn't the writers of our
>respective flavors of UNIX be providing the fixes. I'm not knocking
>David's good intentions, but the DST switch can be viewed as a MAJOR
>software bug worthy of an OFFICIAL update.

The major software bug here is that the DST tables are compiled into
programs.  Arthur Olson of NIH has fixed this; he has posted various
versions of a new flavor of "ctime" that reads the tables from a
file, so if the rules change you just change the file.  (No, stuffing
it into the environment won't work: 1) the environment variable would
have to be immensely long to hold a complete set of rules and 2) if
you decided to get clever and call the environment variable "TZ",
under S3/S5, at least, you'd break *all* the programs out there that
don't expect all this goo in TZ and you'd have to recompile them
all.)

dave@lsuc.UUCP (02/11/87)

In article <1151@ukecc.uky.csnet> edward@ukecc.UUCP (Edward C. Bennett) writes:
>In article <1565@lsuc.UUCP> dave@lsuc.UUCP (David Sherman) writes:
>>	Below is a diff for /usr/src/libc/gen/ctime.c
>>for v7 systems
>
>I think we've all seen this coming, but shouldn't the writers of our
>respective flavors of UNIX be providing the fixes. I'm not knocking
>David's good intentions, but the DST switch can be viewed as a MAJOR
>software bug worthy of an OFFICIAL update.

Absolutely.  But no-one ever maintained v7 systems very officially,
and I doubt anyone does now.  By all means, if you have a UNIX
which is "supported" (say by H-P, DEC or AT&T), lean on your
suppliers to fix the problem.

Incidentally, what happens if you can't fix it? I suppose you
could simply set the clock (i.e., count of time in seconds) forward
an hour on April 5 and back on April 26.  Then, as long as your
software is never fixed, all times reported will be apparently OK.

We have a CT MiniFrame running CTIX (Sys V), by the way. I've
assumed that for that system I may just hack TZ during the relevant
three weeks...

David Sherman
-- 
{ seismo!mnetor  cbosgd!utcs  watmath  decvax!utcsri  ihnp4!utzoo  } !lsuc!dave

guy@gorodish.UUCP (02/13/87)

>Incidentally, what happens if you can't fix it? I suppose you
>could simply set the clock (i.e., count of time in seconds) forward
>an hour on April 5 and back on April 26.  Then, as long as your
>software is never fixed, all times reported will be apparently OK.

Only for suitable values of "OK".  The UNIX notion of time will be
off by one hour, so all times recorded on the file system (either in
inodes or in data files as UNIX time) will be incorrect.

brandx@ihlpl.UUCP (02/16/87)

In article <1569@lsuc.UUCP> dave@lsuc.UUCP (David Sherman) writes:
>Incidentally, what happens if you can't fix it? I suppose you
>could simply set the clock (i.e., count of time in seconds) forward
>an hour on April 5 and back on April 26.  Then, as long as your
>software is never fixed, all times reported will be apparently OK.

Be careful if you're going to set the clock to get around the problem.
1)  Setting the clock forward an hour will not change the fact that
    the system will still view the time as Standard Time.
2)  You'll have to wait until 4AM to move the clock back on the 26th.
    Remember, the hour between 2 and 3 AM doesn't exist on the day
    you're moving the clock back.  (A minute before 3 AM is 1:59 AM,
    not 2:59 AM.)  The software is smarter than you think here.
    I tried to set the clock back an hour after setting it
    forward to 3:15 on April 26.  As makes perfect sense, the time
    changed to 1:15.

    Howard Weisberg

amos@instable.UUCP (02/17/87)

I always thought the whole idea of the BSD way of determining the dst was
extermely redundant - in contrast to the sysV method, in which anyone can
choose whether to have it or not any time, in run time, per process run;
on BSD systems it's a big and ugly routine, compiled into every utility,
and cannot be changed except by root, and then only globally.

It seems all the effort is invested only to present the creating time
of old files as it was at the time of creation - while programs (eg make)
that use it couldnt care less!

In Israel, where dst is erratic (the algorithm depends on the political
constellation and the phases of the moon - no :-) !) I use a small program
that changes the timezone by the settimeofday sys call, and is run twice
a year by 'at'.
-- 
	Amos Shapir
National Semiconductor (Israel)
6 Maskit st. P.O.B. 3007, Herzlia 46104, Israel
(011-972) 52-522261  amos%nsta@nsc.com 34.48'E 32.10'N

guy@gorodish.UUCP (02/17/87)

>I always thought the whole idea of the BSD way of determining the dst was
>extermely redundant

Try "The V7 way of determining..."; putting it into the kernel
antedates 4.2BSD.

>in contrast to the sysV method, in which anyone can choose whether to have
>it or not any time, in run time, per process run; on BSD systems it's a big
>and ugly routine, compiled into every utility,

Whereas on System V, it's *still* a big and ugly routine, compiled
into every utility - or, more to the point, it's a big and ugly
*table*, compiled into every utility, in most UNIX systems out there.
At least Berkeley made an attempt to put tables for areas other than
the US into those utilities (even though there were a number of
errors in the tables).

There *is* a solution; Arthur Olson came up with a version of "ctime"
and friends that reads the DST rules out of a *file*, which is where
they should have been in the first place.  If the rules change, you
just edit a file and compile it into a table; any programs run after
that point will have the correct rules.

The file to be read is selected by the TZ environment variable, so a
user *can* override the default setting if they want.  A program can
also *ignore* the value of TZ; this is required by programs such as
"uucico" that must know the time zone the phone lines are in, *not*
the time zone the user is in.  You can even arrange to give the files
names like EST5EDT, so that you can set TZ to values that will work
with binaries built on systems that don't have this new stuff;
solutions I've seen proposed that encode the rules in the TZ
environment string don't have this property, so they break binary
compatibility (not to mention breaking programs that expect to
convert dates not in the current year - remember, "last year" is, at
certain times, less than one day ago!).

dave@lsuc.UUCP (02/19/87)

In article <13253@sun.uucp> guy@sun.UUCP (Guy Harris) writes:
>>Incidentally, what happens if you can't fix it? I suppose you
>>could simply set the clock (i.e., count of time in seconds) forward
>>an hour on April 5 and back on April 26.  Then, as long as your
>>software is never fixed, all times reported will be apparently OK.
>
>Only for suitable values of "OK".  The UNIX notion of time will be
>off by one hour, so all times recorded on the file system (either in
>inodes or in data files as UNIX time) will be incorrect.

Note that I said, "as long as your software is NEVER fixed". The
internal time may be incorrect, but it would forever (when referring
to times between April 5 and April 27/87, for example) get it "right"
when converting it through localtime().

David Sherman
The Law Society of Upper Canada
-- 
{ seismo!mnetor  cbosgd!utgpu  watmath  decvax!utcsri  ihnp4!utzoo } !lsuc!dave

guy@gorodish.UUCP (02/20/87)

>The internal time may be incorrect, but it would forever (when referring
>to times between April 5 and April 27/87, for example) get it "right"
>when converting it through localtime().

This presumes that no software on the system would be bothered by the
internal time being incorrect; this may be true on some systems, but
I wouldn't make that assumption without studying all the software on
the system (including locally-developed software).