bww@K.GP.CS.CMU.EDU (Bradley White) (01/08/88)
Index: lib/libc/gen/ctime.c 4.3BSD Description: The time routines in the C library know nothing about leap seconds. This means that the correspondence between the number of seconds since the epoch and the actual time of day is broken. Repeat-By: Count the actual number of seconds since January 1, 1970 and run the answer through ctime(3). Notice that the answer is fourteen seconds in the future. Fix: Apply the following patch and then check the output of the test program. main() { long t; t = 567993612; printf("%s", ctime(&t)); t = 567993613; printf("%s", ctime(&t)); t = 567993614; printf("%s", ctime(&t)); } It should look like this (in EST at least). Thu Dec 31 18:59:59 1987 Thu Dec 31 18:59:60 1987 Thu Dec 31 19:00:00 1987 RCS file: RCS/ctime.c,v retrieving revision 1.1 diff -c -r1.1 ctime.c *** /tmp/,RCSt1011358 Wed Jan 6 00:08:34 1988 --- ctime.c Wed Jan 6 00:03:48 1988 *************** *** 321,326 **** --- 321,362 ---- return tmp; } + /* THE LEAP SECOND TABLE SHOULD BE LOADED FROM A FILE */ + + static struct leapsec { + time_t ls_when; + long ls_corr; + } leapsecs[] = { + 78796800, 1, /* 30 Jun 1972 */ + 94694401, 2, /* 31 Dec 1972 */ + 126230402, 3, /* 31 Dec 1973 */ + 157766403, 4, /* 31 Dec 1974 */ + 189302404, 5, /* 31 Dec 1975 */ + 220924805, 6, /* 31 Dec 1976 */ + 252460806, 7, /* 31 Dec 1977 */ + 283996807, 8, /* 31 Dec 1978 */ + 315532808, 9, /* 31 Dec 1979 */ + 362793609, 10, /* 30 Jun 1981 */ + 394329610, 11, /* 30 Jun 1982 */ + 425865611, 12, /* 30 Jun 1983 */ + 489024012, 13, /* 30 Jun 1985 */ + 567993613, 14 /* 31 Dec 1987 */ + }; + + #define NLEAPSECS (sizeof(leapsecs)/sizeof(leapsecs[0])) + + struct leapsec * + lssearch(t) + time_t t; + { + register int i = NLEAPSECS; + + while (--i >= 0) + if (t >= leapsecs[i].ls_when) + return &leapsecs[i]; + return 0; + } + static int mon_lengths[2][MONS_PER_YEAR] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 *************** *** 341,348 **** --- 377,392 ---- register int y; register int yleap; register int * ip; + int ls_flag; + struct leapsec *l; static struct tm tm; + ls_flag = 0; + if (l = lssearch(*clock)) { + if (*clock == l->ls_when) + ls_flag = 1; + *clock -= l->ls_corr; + } tmp = &tm; days = *clock / SECS_PER_DAY; rem = *clock % SECS_PER_DAY; *************** *** 359,364 **** --- 403,415 ---- rem = rem % SECS_PER_HOUR; tmp->tm_min = (int) (rem / SECS_PER_MIN); tmp->tm_sec = (int) (rem % SECS_PER_MIN); + if (ls_flag) + /* + * How should a leap second be represented? + * We choose to add one to tm_sec which will + * usually result in "... ??:59:60". + */ + tmp->tm_sec += 1; tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYS_PER_WEEK); if (tmp->tm_wday < 0) tmp->tm_wday += DAYS_PER_WEEK; -- -- Bradley White <bww@cs.cmu.edu> +1-412-268-3060 CMU Computer Science Department 40 26'33"N 79 56'48"W
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/08/88)
In article <604@PT.CS.CMU.EDU> bww@K.GP.CS.CMU.EDU (Bradley White) writes: > The time routines in the C library know nothing about leap > seconds. This means that the correspondence between the > number of seconds since the epoch and the actual time of > day is broken. The C library time routines are not PERMITTED to know about leap seconds, according to the current draft proposed ANSI C standard. You should set the system clock so that ctime() reports the correct time of day.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/08/88)
In article <6976@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >The C library time routines are not PERMITTED to know about leap >seconds, according to the current draft proposed ANSI C standard. Oops, excuse me -- it is IEEE Std 1003.1 (POSIX) Draft 12 that says this; ANSI C does not dictate what the system time representation is.
ado@elsie.UUCP (Arthur David Olson) (01/09/88)
> > The C library time routines are not PERMITTED to know about leap > > seconds, according to the current draft proposed ANSI C standard. > Oops, excuse me -- it is IEEE Std 1003.1 (POSIX) Draft 12 that > says this; ANSI C does not dictate what the system time > representation is. There is one conflict between leap seconds and draft proposed ANSI C. When the leap seconds occur, the time is "supposed" to be counted thus: ... 23:59:58 23:59:59 23:59:60 00:00:00 00:00:01 00:00:02 ... which means that one or two times a year (typically) the "tm_sec" field of a "struct_tm" should have the value 60. The November '87 draft, though, specifies that tm_sec is confined to the range 0..59. Of course if you're willing to fudge and simply repeat the 23:59:59 or the 00:00:00 there's no problem. (For those using the mod.sources table-based time functions, lines such as # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule US 1988 only - Jan 1 00:00:00 -00:00:01 S do the trick by repeating the 23:59:59; change the "AT" filed to "00:00:01" to repeat the first second of the new year rather than the last of the old.) -- Bugs is a trademark of Warner Brothers/Volkswagen. Time is a trademark of Time-Life Incorporated. -- ado@vax2.nlm.nih.gov ADO, VAX, and NIH are Ampex and DEC trademarks
chongo@amdahl.amdahl.com (Landon Curt Noll) (01/09/88)
In article <6976@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: > >The C library time routines are not PERMITTED to know about leap >seconds, according to the current draft proposed ANSI C standard. >You should set the system clock so that ctime() reports the correct >time of day. I'm opening myself to flames here, but here I go anyway: Yes, I was the one who proposed the following definition which is now in the P1003.1 Draft 12 standard: Epoch: The Epoch refers to the time at 0 hours, 0 minutes 0 seconds, Coordinated Universal Time on January 1, 1970. The value "seconds since the Epoch" refers to the difference in seconds between the referenced time and the Epoch, not counting leap seconds. The function ctime() converts "seconds since the Epoch" into a date/time. The fix from CMU violates the standard. The reason why this was put into the standard was to avoid having to put things like this fix into your code. (most systems do not do this, so the standard reflects this) chongo <> /\oo/\ -- [views above shouldn't be viewed as Amdahl views, or as views from Amdahl, or as Amdahl views views, or as views by Mr. Amdahl, or as views from his house]
guy@gorodish.Sun.COM (Guy Harris) (01/10/88)
> Epoch: > The Epoch refers to the time at 0 hours, 0 minutes 0 seconds, > Coordinated Universal Time on January 1, 1970. The value "seconds > since the Epoch" refers to the difference in seconds between the > referenced time and the Epoch, not counting leap seconds. > > The reason why this was put into the standard was to avoid having to > put things like this fix into your code. (most systems do not do this, > so the standard reflects this) It is worth nothing at this point that most systems also do not provide POSIX-conformant time, and are unlikely ever to do so; instead of providing time in "seconds since the Epoch", they provide the number of seconds since 0 hours, 0 minutes, 0 seconds, SWT (Somebody's Watch Time) on January 1, 1970. It is also worth noting that if a system decided to provide 100% POSIX-conformant time, it would have to ensure that the clock did not advance during a leap second. Think of it this way: a machine's clock provides coordinates along a time axis, starting with 0 at the Epoch and progressing nicely at the rate of one tick per second. A "time", either local or Coordinated Universal, can be thought of as a label applied to a point on this axis. For instance, the label "00:00:01 1/1/70" is applied to the point one second from the Epoch. The coordinates along this time axis correspond most naturally to "time_t"s. "time"s, i.e., the labels, correspond most naturally to "struct tm"s. What most systems do not do is throw leap seconds into the conversion between "time_t" and "struct tm", i.e. into "localtime" and "gmtime". If an implementation wishes to take leap seconds into account, it can either treat "time_t"s as labels (i.e., hold the system clock back on leap seconds) or as coordinates (i.e., throw the leap second conversion into "localtime" and "gmtime", perhaps by doing it the "correct" way and adding a 61st second to some minutes). Most implementations do not do *either* one; the current wording in the standard technically requires implementations to do *something*, namely stop the clock during leap seconds - it does not permit existing implementations to conform down to the last dotted "i" and crossed "t". I would say that what *really* needs to be done is to recognize that few, if any implementations can possibly conform in the strictest sense, as few of them e.g. listen to WWV to set their clocks (and, I suspect, few customers are willing to pay the extra cost of having their system listen to WWV just so that they can be guaranteed not to have their clocks off even by one second), and to indicate that "seconds since the Epoch" merely indicates some reasonable effort to come *close* to seconds since the Epoch. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
admin@wundt.psy.vu.nl (Wundt Administrator) (01/11/88)
In several articles precedding this a " bug " in ctime is discussed. I really couldn't care much about 14 secs in 18 plus years. My Watch Time (or SWT, if you prefer) is often off by more than 14 secs anyway. Further, the other U*IX sites we connect don't aggree with MWT either. We differ by (oh gosh !!) minutes occainsionally. Fortunately, noone has suffered (tremendously) from this. Michael Felt In article <38377@sun.uucp> guy@gorodish.Sun.COM (Guy Harris) writes: >I would say that what *really* needs to be done is to recognize that few, if >any implementations can possibly conform in the strictest sense, as few of them >e.g. listen to WWV to set their clocks (and, I suspect, few customers are >willing to pay the extra cost of having their system listen to WWV just so that >they can be guaranteed not to have their clocks off even by one second), and to >indicate that "seconds since the Epoch" merely indicates some reasonable effort >to come *close* to seconds since the Epoch.
gwyn@brl-smoke.UUCP (01/12/88)
In article <1964@rti.UUCP> trt@rti.UUCP (Thomas Truscott) writes: >I SUGGEST THAT POSIX >1. Encourage fixes for the leap-second and other problems of ctime() > and related programs. >2. Document that application of such fixes is recommended. I agree with Tom's analysis and recommendations. Note that the "epoch" in practice is really whatever is obtained by the inverse of ctime() built into the set-date command, whenever a system administrator looks at the wall clock to set the system time. It isn't really 00:00:00, Jan 1, 1970, although it will usually be close to it (unless the administrator is purposely establishing a fake date for some reason, which occasionally is useful). No amount of standardization will change this fact of life, so the definitions should make as much sense as possible. I could accept having the POSIX standard permit implementations to maintain a "reasonably close" approximation to whatever is defined. Only sites with extremely good connections to a controlled time reference have much chance of being within a tick of the theoretically "correct" time setting anyway. That would clearly be demanding too much precision. The most useful thing for ctime() to report would be something very close to the wall-clock time at which the corresponding time() function was invoked. Whether the number of seconds since some artifical epoch is exact or not is of no consequence to most non-astronomical applications.
trt@rti.UUCP (Thomas Truscott) (01/12/88)
> I really couldn't care much about 14 secs in 18 plus years.
Yes, 14 secs one way or another is no big deal.
So you won't care if someone fixes the leap-second bug in ctime, right?
AS WE ALL KNOW
UNIX (and other systems) internally maintains the seconds that have
elapsed since <EPOCH>. If at a given instant the elapsed time is 't',
then one second later the elapsed time will be 't+1'.
This is unaffected by time zones, daylight savings time,
leap days, leap seconds, or any other artifacts of man.
This is the fundamental representation of time in UNIX (and other systems):
other representations are derivatives and should be treated as such.
AND THEREFORE
The ctime() routine, which converts "EPOCH time" such as
568924849
into something more understandable by man such as
Mon Jan 11 13:40:49 1988
must take into account the artifacts such as time zones, etc.
including *leap seconds* or else ctime() will produce the wrong answer!
Similarly for the inverse routines ("getdate", "timec", any standards yet?)
that convert a user-supplied date into EPOCH time.
DO NOT ATTEMPT TO FIX THE BUG BY DOCUMENTING IT!
We might document "ignore leap seconds" but that results in
small but very real errors that someday could cause real harm.
Should we document "ignore the difference between sidereal
and solar timekeeping systems"?
There is no end to this!
I SUGGEST THAT POSIX
1. Encourage fixes for the leap-second and other problems of ctime()
and related programs.
2. Document that application of such fixes is recommended.
Tom Truscott
chongo@amdahl.amdahl.com (Landon Curt Noll) (01/13/88)
In article <1964@rti.UUCP> trt@rti.UUCP (Thomas Truscott) writes: >Yes, 14 secs one way or another is no big deal. >So you won't care if someone fixes the leap-second bug in ctime, right? And by the same logic, you won't care if we all don't fix it, right? >DO NOT ATTEMPT TO FIX THE BUG BY DOCUMENTING IT! >We might document "ignore leap seconds" but that results in >small but very real errors that someday could cause real harm. But there exists software that would dislike to see: 23:59:60. That is an example of real harm NOW if we require a change or leave open the choice to vendors. If you leave it up to the vendors to fix or not fix time based on leap seconds, then you could be faced with synced machines on a localarea net converting into or out of timestamps differently. The 14 seconds between synced machines could be a non-trivial difference. Since the Earth is unlikely to obtain a boost of rotational energy, this difference is likely to increase in the future. :-) Or consider two machines from two different vendors: Vendor DOES Vendor DOESNOT ----------- -------------- keeps track of leap seconds does not keep track of leap seconds If I ask 'DOES' and 'DOESNOT' to give me the string produced by asctime(gmttime(some_fixed_timestamp)), I could get different values! If I ask them to convert the same ascii time string (assume it is GMT based time) into a timestamp, I could get different values! We have 3 main choices: 1) leave the timestamp conversion alone (>99% don't do leap seconds) 2) force systems to do leap seconds (a change with doubtful value transition problems and retroactive change problems) 3) allow systems to select their option (problems with synced systems) I vote for #1. chongo <> /\oo/\ -- [views above shouldn't be viewed as Amdahl views, or as views from Amdahl, or as Amdahl views views, or as views by Mr. Amdahl, or as views from his house]
chongo@amdahl.amdahl.com (Landon Curt Noll) (01/13/88)
In article <7040@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >The most useful thing for ctime() to report would be something >very close to the wall-clock time at which the corresponding >time() function was invoked. Whether the number of seconds since >some artifical epoch is exact or not is of no consequence to most >non-astronomical applications. I think some people are mis-understanding the point: POSIX does not say that a conforming machine MUST have the correct time! What it does say is that given some specific time, it MUST produce the same timestamp. chongo <> /\oo/\ -- [views above shouldn't be viewed as Amdahl views, or as views from Amdahl, or as Amdahl views views, or as views by Mr. Amdahl, or as views from his house]
guy@gorodish.Sun.COM (Guy Harris) (01/13/88)
> POSIX does not say that a conforming machine MUST have the correct time! *Portable Operating System Interface for Computer Environments", P1003.1/DRAFT 12, October 12, 1987, page 24: Epoch The Epoch refers to the time at 0 hours, 0 minutes, 0 seconds, Coordinated Universal Time on January 1, 1970. The value "seconds since the Epoch" refers to the difference in seconds between the referenced time and the Epoch, not counting leap seconds. Page 81: 4.5.1 Get System Time Function: time() ... 4.5.1.2 Description The time() function returns the value of time in seconds since the Epoch (see Epoch (section)2.3). Sorry, but POSIX DOES say that a conforming machine MUST have correct time, or more precisely it must have the correct time minus the number of leap seconds since 0 hours, 0 minutes, 0 seconds, Coordinated Universal Time on January 1, 1970. I.e, if at some time T it is currently 569,022,442 seconds since the point in time labelled as 0 hours, 0 minutes, 0 seconds, Coordinated Universal Time on January 1, 1970 (which is roughly what it is as I type this), the difference in seconds between the referenced time and the Epoch is 569,022,442. There have been 14 leap seconds between that time and the Epoch; were some timekeeper not to count those seconds, it would have counted only 569,022,428 seconds. Thus, at that time T, a call to "time()" on a POSIX system returns 569,022,428. Not 569,022,442; not 469,022,368; not 569,022,488. > What it does say is that given some specific time, it MUST produce the > same timestamp. What does "it MUST produce the same timestamp" mean? If it means "all POSIX systems must, if 'time()' is called at some time T, return the same value", then it certainly says that - it also says what that value must be! Furthermore, it says that this value must NOT include leap seconds, which means that if the system e.g. keeps time by bumping a counter every second it must avoid doing so for leap seconds. That may not have been what you MEANT to have POSIX say, but it's what you DID make POSIX say. If that's not what you meant, you'll have to try again. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
guy@gorodish.Sun.COM (Guy Harris) (01/13/88)
> If you leave it up to the vendors to fix or not fix time based on leap > seconds, then you could be faced with synced machines on a localarea net > converting into or out of timestamps differently. Please define what a "timestamp" is! Is a "timestamp" a value as returned by "time()", or a value as returned by "time()" and subsequently convered by "localtime()" or "gmtime()"? The time stamps that are applied to files by UNIX systems tend to be the former, as do the fundamental notion of time in such systems. I infer from your other statements, though, that you use the latter notion of "timestamp". The problem you cite - "struct tm" values with "tm_sec" equal to 60 - has NOTHING WHATSOEVER to do with the former ("time_t" time stamps), only the latter. Therefore, to fix this problem, the definition of "seconds since the Epoch" need not be changed; the net result will be that a system that keeps "perfect" time (i.e., the system clock, as returned by "time()", was correctly set to the number of seconds since the Epoch - *counting* leap seconds, i.e. ignoring the artifacts of human-developed timekeeping systems that attempt to correlate time values to the behavior of heavenly bodies - is incremented by one precisely every second) will generate "struct tm" values that slowly drift with respect to what various time standards showing time values using the aforementioned timekeeping systems say. The only way to fix this drift would either be to 1) change "localtime" to take leap seconds into account or 2) change the system so that the values returned by "time" take leap seconds into account. In short, you CAN'T fix it without teaching systems about leap seconds if they do not already use clocks that know about leap seconds. > The 14 seconds between synced machines could be a non-trivial difference. Yes, for programs that use "struct tm" values and expect them to match up. No, for programs that use "time_t" values and expect them to match up. Therefore, the wording in the definition of "Epoch" in the front of P1003.1 is completely wrong, as it requires implementations to keep track of leap seconds anyway (if you don't believe me, please read my previous article and Tom Truscott's article and refute the points stated therein). If you believe that the conversions performed by "localtime" and "gmtime" should not take leap seconds into account (a position that is subject to debate - I'll let Tom Truscott take the view opposed to yours on this), please *fix* the definition of "Epoch" and change the writeups on "localtime" and "gmtime" instead. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/13/88)
In article <20700@amdahl.amdahl.com> chongo@amdahl.amdahl.com (Landon Curt Noll) writes: >POSIX does not say that a conforming machine MUST have the correct time! >What it does say is that given some specific time, it MUST produce the >same timestamp. Quoting IEEE Std 1003.1 Draft 12: The Epoch refers to the time at 0 hours, 0 minutes, 0 seconds, Coordinated Universal Time on January 1, 1970. The value "seconds since the Epoch" refers to the difference in seconds between the referenced time and the Epoch, not counting leap seconds. The time() function returns the value of time in seconds since the Epoch. [There are also specific extensions to the asctime() function that aren't relevant to the discussion.] I believe it pretty clearly specifies what time() must return. I would call that "the correct time" (expressed in seconds since the Epoch, with the wart of having to know how many leap seconds to leave out). By the way, It might be nice to specify that this is the intent of time(), without insisting on exactness, since not only are most systems not synchronized with standard time references, but also one never knows how long a system call will actually take to complete. ANSI X3.159-198x specifies that the localtime(), gmtime(), and ctime() functions convert the system time (what time() returns) into the usual fields (year, month, week, day, hour, minute, second, etc.). No surprises here. ---------- Mappings: genuine uniform time ---> genuine time since Epoch (by specification of when the Epoch is) genuine time since Epoch ---> Draft 12 "time since Epoch" (by omitting leap seconds) Draft 12 "time since Epoch" ---> system time (equivalence specified by Draft 12) system time ---> broken-down time (by gmtime() or localtime()) broken-down time ---> string at user interface (by asctime()) note: ctime = asctime(localtime) The two quantities of interest are the "system time" returned by time(), and the string seen at the user interface, which undoubtedly should correspond as closely as possible with the time of day on the wall clock. The above mappings are all invertible (except near leap seconds), so if a user-interface form of time is specified, as when the system administrator "sets the time", we can track backwards to determine what "system time" the operating system maintains. Chongo apparently wanted to make the fourth mapping arithmetically simpler, which is why leap secons are not visible to it. Unfortunately, when a leap second does occur, the user-interface time is supposed to exhibit a glitch, which it can only do if someone deliberately resets the system time to force the glitch. How much smoother it would be if the system clock did not need to be reset in order to keep the user-interface times tracking the official wall clocks. This could be accomplished by instead using the following mappings: genuine uniform time ---> genuine time since Epoch (by specification of when the Epoch is) genuine time since Epoch ---> system time (equivalence recommended instead of Draft 12's) system time ---> broken-down time (by gmtime() or localtime()) broken-down time ---> string at user interface (by asctime()) note: ctime = asctime(localtime) This may seem like a minor difference, but it has practical effects: It would leave the kernel clock runnning uniformly even across a leap second, and with a bit more work in gmtime()/localtime() the leap seconds can be allowed for and reported properly, as in the original "bug fix" that prompted this discussion. An added bonus is that the "seconds since the Epoch" would mean just that, which is more useful than the Draft 12 meaning, if one really does have a synchronized system clock and cares about absolute time references (for example, for event logging). Two things are needed to achieve this: Leap seconds need to be reinstated into "seconds since the Epoch" in IEEE Std 1003.1. tm_sec must be allowed to hold the value 60 for a leap second in ANSI X3.159-198x. (There really are 61 seconds in some minutes, just as there really are 29 days in some Februaries.) If we can get agreement on this, there may still be time to get this fixed before these standards are frozen.
bww@K.GP.CS.CMU.EDU (Bradley White) (01/13/88)
So, it seems we are all in agreement. POSIX undoubtedly said the opposite of what it meant, and system clocks should keep ticking during leap seconds (just like our hearts). Now, "time_t" -> "struct tm" conversion routines already do different things in different timezones, so outlawing allowances for leap seconds seems indefensible. The only requirement should be that any "struct tm" -> "time_t" function make the same allowances. The remaining issue, for those who care for leap seconds, is a good implementation. Clearly something based upon adotime (ado says that ado is a trademark of something) is appropriate, although I don't think a copy of the leap second rules in every timezone file as ado earlier suggested is best; nor did this address the ??:59:60 issue. -- Bradley White <bww@cs.cmu.edu> +1-412-268-3060 CMU Computer Science Department 40 26'33"N 79 56'48"W
guy@gorodish.Sun.COM (Guy Harris) (01/14/88)
I decided to see what RFC 822 had to say, if anything, on the subject of representing dates. It says: 5. DATE AND TIME SPECIFICATION 5.1. SYNTAX date-time = [ day "," ] date time ; dd mm yy ; hh:mm:ss zzz day = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun" date = 1*2DIGIT month 2DIGIT ; day month year ; e.g. 20 Jun 82 month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec" time = hour zone ; ANSI and Military hour = 2DIGIT ":" 2DIGIT [":" 2DIGIT] ; 00:00:00 - 23:59:59 The reference to 23:59:59 is in a comment, so it's not clear whether this means that 23:59:60 in an header would violate this specification or not. Section 2.8 "; COMMENTS" says A semi-colon, set off some distance to the right of rule text, starts a comment that continues to the end of line. This is a simple way of including useful notes in parallel with the specifications. which I infer means that it is a note, not a part of the specification. From that, I presume that it was assumed that everybody would know what the Right Thing to do was and that they'd do it, and no formal specification was necessary. I don't know if they took the possibility of leap seconds into account or not. RFC 822 also refers to the document ANSI. "Representations of Universal Time, Local Time Differen- tials, and United States Time Zone References for Information Interchange," X3.51-1975. American National Standards Insti- tute: New York (1975). I don't know if this document says anything about leap seconds or not, because I don't have a copy of it. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
dupuy@westend.columbia.edu (Alexander Dupuy) (01/16/88)
In article <7562@elsie.UUCP> ado@elsie.UUCP (Arthur David Olson) writes: >Of course if you're willing to fudge and simply repeat the > 23:59:59 >or the > 00:00:00 >there's no problem. (For those using the mod.sources table-based time >functions, lines such as > > # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S > Rule US 1988 only - Jan 1 00:00:00 -00:00:01 S > >do the trick by repeating the 23:59:59; change the "AT" filed to "00:00:01" >to repeat the first second of the new year rather than the last of the old.) Here's a revision of the tzone/etcetera zoneinfo source file which corrects for leap seconds in UTC (not GMT though - so the GMT rules are consistent with the standard ctime results). After all, if you are a real clockwatcher, and care about things like leap seconds, you have "TZ=UTC" in your .profile, right? Aside from the problem of ctime not generating 23:59:60, zic also sets the dst flag in the zoneinfo files for any rule with nonzero SAVE, even though (in this case) the time is standard. You can go and clear the flag with a binary editor if you care, or you could hack zic. By setting up the rules as decreasingly positive offsets to GMT, we can make UTC a "standard" time with 0 offset from GMT for all times since the last leap second, which is good enough for most purposes. Note also that you must not have NOSOLAR defined, since this creates 14 different UTC savings times. You can work around this by deleting the first 5 leap second rules, at the expense of inaccuracy for years < 1975. @alex --- arpanet: dupuy@columbia.edu uucp: ...!rutgers!columbia!dupuy #!/bin/sh : This is a shar archive. Extract with sh, not csh. : The rest of this file will extract: : : etcetera : echo x - etcetera sed 's/^X//' > etcetera << '//go.sysin dd *' X# @(#)etcetera 3.2 X X# X# We leave GMT without adjustments for leap seconds, for simplicity X# X X# Zone NAME GMTOFF RULES FORMAT [UNTIL] XZone GMT 0 - GMT X X# X# Names for zones that might exist, just so people can set a timezone X# that's right for their area, even if it doesn't have a name or dst rules X# (half hour zones are too much to bother with -- when someone asks!) X# X XZone GMT-12 -12 - GMT-1200 XZone GMT-11 -11 - GMT-1100 XZone GMT-10 -10 - GMT-1000 XZone GMT-9 -9 - GMT-0900 XZone GMT-8 -8 - GMT-0800 XZone GMT-7 -7 - GMT-0700 XZone GMT-6 -6 - GMT-0600 XZone GMT-5 -5 - GMT-0500 XZone GMT-4 -4 - GMT-0400 XZone GMT-3 -3 - GMT-0300 XZone GMT-2 -2 - GMT-0200 XZone GMT-1 -1 - GMT-0100 XZone GMT+1 1 - GMT+0100 XZone GMT+2 2 - GMT+0200 XZone GMT+3 3 - GMT+0300 XZone GMT+4 4 - GMT+0400 XZone GMT+5 5 - GMT+0500 XZone GMT+6 6 - GMT+0600 XZone GMT+7 7 - GMT+0700 XZone GMT+8 8 - GMT+0800 XZone GMT+9 9 - GMT+0900 XZone GMT+10 10 - GMT+1000 XZone GMT+11 11 - GMT+1100 XZone GMT+12 12 - GMT+1200 XZone GMT+13 13 - GMT+1300 # GMT+12 with DST X XLink GMT Greenwich X X# X# For the dedicated clockwatchers, true UTC with leap second adjustments X# (not that this will not work if NOSOLAR is defined) X# X X# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S XRule Leap min only - Jan 1 00:00:00 00:00:14 - XRule Leap 1972 only - Jul 1 00:00:00 00:00:13 - XRule Leap 1973 only - Jan 1 00:00:00 00:00:12 - XRule Leap 1974 only - Jan 1 00:00:00 00:00:11 - XRule Leap 1975 only - Jan 1 00:00:00 00:00:10 - XRule Leap 1976 only - Jan 1 00:00:00 00:00:19 - XRule Leap 1977 only - Jan 1 00:00:00 00:00:08 - XRule Leap 1978 only - Jan 1 00:00:00 00:00:07 - XRule Leap 1979 only - Jan 1 00:00:00 00:00:06 - XRule Leap 1980 only - Jan 1 00:00:00 00:00:05 - XRule Leap 1981 only - Jul 1 00:00:00 00:00:04 - XRule Leap 1982 only - Jul 1 00:00:00 00:00:03 - XRule Leap 1983 only - Jul 1 00:00:00 00:00:02 - XRule Leap 1985 only - Jul 1 00:00:00 00:00:01 - XRule Leap 1988 only - Jan 1 00:00:00 00:00:00 - X X# Zone NAME GMTOFF RULES FORMAT [UNTIL] XZone UTC 0 Leap UTC X XLink UTC UCT XLink UTC Universal //go.sysin dd * exit --- arpanet: dupuy@columbia.edu uucp: ...!rutgers!columbia!dupuy