Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!decvax!decwrl!amdcad!lll-crg!caip!ut-sally!std-unix From: std-u...@ut-sally.UUCP Newsgroups: mod.std.unix Subject: RFC.001 Timezones Message-ID: <5350@ut-sally.UUCP> Date: Thu, 17-Jul-86 18:46:09 EDT Article-I.D.: ut-sally.5350 Posted: Thu Jul 17 18:46:09 1986 Date-Received: Fri, 18-Jul-86 03:51:17 EDT Organization: IEEE 1003 Portable Operating System for Computer Environments Committee Lines: 23 Approved: j...@sally.UUCP This is the first of a series of five articles about timezones. It is posted to make public previous discussions in this area and not to stir up the issue again. The time is propitious because the U.S. President has just signed a new daylight savings time law. The other four articles of this series form RFC.001, which was submitted to the IEEE 1003.1 Working Group in Florence on 18 April 1986. The set of articles is as follows: V6N29 RFC.001 Timezones: this article (not part of RFC.001 proper). V6N30 RFC.001 Summary of mod.std.unix Volume 5 by the moderator. V6N31 RFC.001 Timezone Interface (reposting of V5N65) by Robert Elz. V6N32 RFC.001 Timezone Examples (from V5N57) by Arthur Olson. (just the examples from the last few pages, not the whole article). V6N33 RFC.001 Time Zone Proposal by jsq. The last item has the same intent as the Elz article but is in a form which should be usable as an actual proposal. It may be submitted as such soon. There was another RFC (from HP) which solved all the same problems but by a slightly different mechanism. Perhaps its author would like to post it? Volume-Number: Volume 6, Number 29
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!decvax!decwrl!amdcad!lll-crg!caip!ut-sally!std-unix From: std-u...@ut-sally.UUCP Newsgroups: mod.std.unix Subject: RFC.001 Summary of mod.std.unix Volume 5. Message-ID: <5351@ut-sally.UUCP> Date: Thu, 17-Jul-86 18:53:24 EDT Article-I.D.: ut-sally.5351 Posted: Thu Jul 17 18:53:24 1986 Date-Received: Fri, 18-Jul-86 03:52:06 EDT Organization: IEEE 1003 Portable Operating System for Computer Environments Committee Lines: 95 Approved: j...@sally.UUCP Summary of time zone discussion (and other material) in mod.std.unix Volume 5. The time zone discussion was in response to a request in P1003 Appendix A.3. The numbers in parentheses like (N3) correspond to article number within Volume 5. The *problem* was first stated by Mark Horton (N3). * GMT/local time disparities exist in the real world: Internal system time must be GMT (N11) as used by make (N6), etc. Many log files are in local time, e.g., RCS, SCCS (N15). Users want to see dates displayed in local time (N3). Some parameter files are in local time, such as UUCP's L.sys (N5), crontab (N13), and at (N69). Conversions should work for dates from at least 1 Jan 1970 (N26) (for ls, SCCS, RCS, other logs) to near future (L.sys, crontab, at) (N65). * Network/dialup logistics: Synchronization of networked hosts also requires internal GMT (N17). Some network-related logs should perhaps be in GMT (N10). Users may be in different timezones than hosts (N7, N14, N13). Client workstations may be in different time zones than servers (N63). * Politics in the real world sets time zones: There are many standard one-hour-from GMT timezones (STs); some of them may have different names in different countries. There are many Dalight Savings Times (DSTs) related to STs, usually by adding one hour. These DSTs differ even within the same ST (N63). Double daylight savings time is sometimes used (N62, N58). Even daylight losing time is plausible (N51, N65). Sometimes the DST offset from ST is not integral hours (N28). There are local times which are not DSTs and also not integral hours from GMT (N19, N13). Offset precision of minutes is necessary (N19) but seconds not (N63). ST may change at any time (China switching to several zones, N62). DST may change at any time and with little notice (Australia, N65). or for brief periods (U.S. presidential elections, N27). Timezone names may conflict (Bering Strait Time/British Summer Time) or be non-alphabetic (N54, N48). Some *deficiencies* of existing implementations (N3). * V7/BSD: inefficiency of system call. * System III/V: initialization and security (N3, N66, N63, N4, N50); one hour precision is not enough (N63). * both: DST tables wired into kernel or library, respectively. Proposed *solutions*. * Early proposals by Kenneth Almquist (N24) and Bob Devine (N47) were very useful for discussion but flawed. * Interface as proposed by Robert Elz (N65): Three conversions sufficient: GMT, default local, user's local (N55). Timezone format left to the implementation. Timezone in environment allowed. Default initialization and security provided. (A routine to translate timezone name to offset possibly useful (N67).) Proposed *implementation* by Arthur Olsen (N68,N57) since posted to mod.sources. * Inspired Elz's interface and is sufficient for it (N65). * Jack Jansen's implementation would also fit Elz's interface (N65). * Miscellaneous implementation criteria: Should not be shell-specific (N49). Should not put timezone offset in u-area (N22, N21, N20). Efficiency requirements (N66): conversion of present time fast for logging, of near past pretty fast for "ls -l", of distant past may be slow. * A particular implementation may be broad or narrow, depending on the intended market (N65, N63). Far *future* considerations. * Machines are currently considered stationary (N60). * Days may not be of 24 hours (N58). * Announcement of info-futures list (N59). Other topics in mod.std.unix Volume 5, with numbers of the corresponding sections of the IEEE 1003.1 Trial Use Standard: setuid and environment clearing (N39, N31) 3.1.2. setuid switching (N46, N45, N44, N43) 4.2.2. ex-directory (N12, N8) directory umask 5.3.3, 5.6.1. motivation (N35, N23, N22) objections (N34, N33, N25) proposals to use .cshrc (N30, N35, N29) clarifications: not per cwd (N38); process umask remains (N40) philosophy (N42, N37) solution (N41) The IEEE 1003 Committee and mod.std.unix (N36, N33, N35) Draft 6 (N2) meetings: Denver (N18); Florence (N71). administrativia (N1, N30). guest moderator (N71, N70). End of summary of mod.std.unix Volume 5. Volume-Number: Volume 6, Number 30
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!decvax!decwrl!amdcad!lll-crg!caip!ut-sally!std-unix From: std-u...@ut-sally.UUCP Newsgroups: mod.std.unix Subject: RFC.001 Timezone Interface Message-ID: <5352@ut-sally.UUCP> Date: Thu, 17-Jul-86 19:03:01 EDT Article-I.D.: ut-sally.5352 Posted: Thu Jul 17 19:03:01 1986 Date-Received: Fri, 18-Jul-86 03:52:53 EDT Organization: IEEE 1003 Portable Operating System for Computer Environments Committee Lines: 193 Approved: j...@sally.UUCP [ This is part of RFC.001 and is a reposting of V5N65. -mod ] Date: 02 Mar 86 05:47:32 +1100 (Sun) From: Robert Elz <munnari!...@SEISMO.CSS.GOV> >Subject: localtime(), ctime() and timezones It seems to me that this discussion is getting a bit overblown, as far as P1003 is concerned, it doesn't really seem to be as difficult or complex as some people are making out. So, I'm going to propose something that could be inserted into P1003 (with the obvious extra definitions that I'm going to leave out on the assumption that everyone knows what they are, like the definition of a "struct tm"). In some words of other, it would go like this (with hopefully a lot of cleaning up of the typography to get rid of quotes and things like that where I would really prefer to use italics or bold): Implementations shall provide the following functions: struct tm *gmttime(t) time_t *t; struct tm *localtime(t) time_t *t; int settz(p) char *p; char *asctime(tp) struct tm *tp; char *ctime(t) time_t *t; gmttime: converts the time_t "*t" to a "struct tm" representing the same time (in Universal Co-ordinated Time). (waffle about the returned value being in a static area, etc, goes here). localtime: converts the time_t "*t" to a "struct tm" representing the given time adjusted to represent some local time difference. "local time" will be specified by a call to "settz", if no such call has preceded the call to localtime(), localtime() will call "settz(getenv("TZ"));". Implementors should note that for any defined past time (from midnight January 1, 1970 until the time the call is made) the local time returned should be accurate (taking into account the effects of daylight saving, if any). For future times, the local time returned should be as likely to be accurate as current projections of future timezone rules and daylight saving time changes allow. settz: enables users to specify the local time conversion to be used by localtime. The string is an implementation specific representation of the timezone offset desired, with 2 special cases.. The null pointer (t == (char *)0) will always select the appropriate local time offset for the host executing the call. A null string (t != (char *)0 && *t == '\0') will select no local time transformations (making localtime() equivalent to gmttime()). Implementations should provide, and document, some mechanism to allow users to select another timezone. This mechanism is beyond the scope of the standard. Implementors should, if possible, allow users to define their own timezones, and not restrict them to use one of some standard set. If settz is called with an unrecognisable argument, the effect is implementation defined. (Users might expect any of three "reasonable"? actions could be taken here -- use GMT, use local time, or use local time in the area where the implementation was performed). settz returns 0 if the timezone selected could be obtained, and -1 otherwise. settz can be called as many times as needed, each call affects future calls of localtime, until another call to settz. acstime: returns a 25 character string representing the time specified by "*tp". The format of the string is ... (you all know it). ctime: is defined to be "asctime(localtime(t))". ................... Notes: this is (about) the right level of detail for the standard. There is no need to specify what the form of the argument to settz() is. This enables things like the Sys V "EST5EDT" string, and Arthur Olson's (elsie!ado) "localtime" "Eastern" etc, to all be used with impunity - the implementor gets to choose whatever is appropriate to him - just provided that he can satisfy the needs of his customers (implementors who provide no means of getting daylight saving right in the Southern hemisphere can probably expect not to sell many copies there - but that's their choice). In particular - this discourages programmers from writing programs which "know" what the local time should be - there's no reason at all why a program should ever need to do more than select GMT, host local time, or a user specified time zone. (nb: while localtime uses the TZ environment variable in cases where the program has made no call to settz(), there's nothing to stop a program getting the argument to settz() from anywhere it pleases, including from several different environment variables if it chooses, and needs to operate in several timezones, or from an external configuration file, or wherever is appropriate). This works for existing programs (in general) - localtime() performs the required call to settz() the first time it is called (directly or via ctime()). There's no need to worry about who sets TZ, if its not set, getenv("TZ") will return (char *)0 and settz() will then use the appropriate local time for the host. How settz() gets that information is an implementation matter. The security problems (people faking local time for programs that expect it to be host local time, by setting TZ before running the program) can easily solved by causing those (comparatively few) programs to do "settz((char *)0)" before their first call to localtime(). What's missing: So far here there is no mention of the "timezone name". None of the standard mechanisms is really adequate here. The V7 (and 4.xbsd) "timezone" function is clearly inadequate (although 4.2 bsd allows users to set the environment variable TZNAME to anything they like) since there can clearly be several possible names for the same offset, and "timezone" has no way to discover which one is wanted. Requiring the name to resice in the environment somewhere (Sys V) is also inadequate (there are too many problems about making sure it is set in all the right places). Arthur Olson's scheme causes "localtime" to set a global variable "tz_abbr" to the correct string name for the timezone just used. I can't think of any cases where anything more than this is needed, but it is less flexible then "timezone()" and it would require programs that currently call timezone() to have to be altered. (He also has his version of "ctime" (but not "asctime") include the timezone in its output - I doubt if that is feasible for P1003, too many existing programs know what every byte in the returned string from ctime() contains.) I solicit suggestions for what to do here - one might be to retain "timezone" but not require that it be capable of returning anything except the zone name corresponding to the last call of localtime() - then with ado's implementation it could simply ignore its arguments and return tz_abbr - I suspect that would satisfy all existing uses (and the ones it doesn't are quite likely not to work in general anyway). Opinions? There's also no discussion of how this relates to processes and images. Not because there's anything doubtful here, but just because the necessary words take a lot of space. (informally, "the first call to localtime" is intended to be "the first after the program is exec'd, ignoring any fork()'s it may have since performed, as long as there has been no subsequent exec). Getting this kind of thing right is essential for a standatds document, its not essential here. ................... A justification for all this ... Today, just about 2 1/2 hours ago (it's early on a Sun morning as I write this) the daylight saving rules changed in at least 2 Australian states (no-one really seems very sure of what happened, or really why). The politicians gave us less than a month's warning that it was coming (and the month was February, which isn't a long month...). If there's anyone who doesn't believe that some form of dynamic timezone setting is required, they're welcome to come to Australia and suffer our local politicians (this isn't the first time: a couple of years ago New South Wales decided to extend daylight saving for a month to try and save on power bills - the amount of notice given was about the same - at that time, at least one local site decided to scrap running on GMT and run on localtime (ala VMS) instead. They're still doing that, I think, and suffering because of it). I'm extremely grateful that Arthur Olson decided to try an implementation, and donate it to the community - he made the task of converting things here much easier than it otherwise would have been. His implementation meets the above specs (in fact, it inspired them...), and will work for all the contorted exampes that people have been proposing (multiple shifts in a year, multi-hour saving, even daylight wasting). But note - there's no need for the standard to require this generality, market pressures will do that - all the standard needs to do is supply a suitable interface. Arthur Olson's implementation proves that the above reccomendation is implementable (munnari is running his code, in libc, right now) and effecient enough. [ Your last sentence gives the reason that I've encouraged discussions of implementations in the newsgroup: it's good to know that a proposed standard is implementable and handles actual cases. But you're right, of course, that the P1003 standard doesn't need implementation details. -mod ] Jack Jansen's (mcvax!jack) somewhat similar, but slightly different scheme would probably work just as well. Bob Devine's (hao!asgb!devine) "I don't think its needed" attitude can also fit the standard - if he's right then he's probably going to have a very fast localtime() which will serve him well. If he's wrong, then he's not going to get many customers. That's good - the more the better - that gives us users (or us system implementors perhaps) a wide choice of methods. Robert Elz kre%munnari...@seismo.css.gov seismo!munnari!kre Volume-Number: Volume 6, Number 31
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!decvax!decwrl!amdcad!lll-crg!caip!ut-sally!std-unix From: std-u...@ut-sally.UUCP Newsgroups: mod.std.unix Subject: RFC.001 Timezone Examples Message-ID: <5353@ut-sally.UUCP> Date: Thu, 17-Jul-86 19:06:37 EDT Article-I.D.: ut-sally.5353 Posted: Thu Jul 17 19:06:37 1986 Date-Received: Fri, 18-Jul-86 03:49:53 EDT Organization: IEEE 1003 Portable Operating System for Computer Environments Committee Lines: 324 Approved: j...@sally.UUCP [ This is part of RFC.001 and is a reposting of some examples from V5N57. Note that the current version of Arthur Olsen's implementation is to be found in the mod.sources archives, not in mod.std.unix. This posting is intended merely to illustrate the variety of possible timezones. -mod ] echo tzcomp.8 1>&2 cat >tzcomp.8 <<'End of tzcomp.8' .TH TZCOMP 8 .SH NAME tzcomp \- time zone compiler .SH SYNOPSIS .B tzcomp [ .B \-d directory ] filename ... .SH DESCRIPTION .I Tzcomp reads text from the file(s) named on the command line and creates the time zone information files specified in this input. If a .I filename is .BR ` - ', the standard input is read. .PP This option is available: .TP .B \-d directory Create time zone information files in the named directory rather than in the standard directory named below. .PP A sharp characters (#) in the input introduces a comment which extends to the end of the line the sharp character appears on. Any line which is blank (after comment stripping) is ignored. Non-blank lines are expected to be of one of three types: rule lines, zone lines, and link lines. .PP A rule line has the form .nf .B .ti +.5i .ta \w'Rule 'u +\w'MostNA 'u +\w'FROM 'u +\w'1973 'u +\w'TYPE 'u +\w'Apr 'u +\w'lastSun 'u +\w'2:00 'u +\w'SAVE 'u .sp Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S .sp For example: .ti +.5i .sp Rule MostNA 1969 1973 - Apr lastSun 2:00 1:00 D .sp .fi The fields that make up a rule line are: .TP .B NAME Gives the (arbitrary) name of the set of rules this rule is part of. .TP .B FROM Gives the first year in which the rule applies. .TP .B TO Gives the last year in which the rule applies. The word .RB ` only ' may be used to repeat the value of the .B FROM field. .TP .B TYPE Gives the type of year in which the year applies. If .B TYPE is .B "-" then the rule is taken to apply in all years between .B FROM and .B TO inclusive. If .B TYPE is something else, then the command .B .ti +.5i years from to type .br is executed with arguments .IR from , .IR to , and .IR type taken from the rule line; the rule is taken to apply only in those years printed by the .I years command. The distributed .I years command is a shell script that can handle year types .B uspres (United States presidential election years) and .B nonpres (all other years); other year types may be added by changing the script. .TP .B IN Names the month in which the rule takes effect. Month names may be abbreviated. .TP .B ON Gives the day on which the rule takes effect. Recognized forms include: .nf .in +.5i .sp .ta \w'lastSun 'u 5 the fifth of the month lastSun the last Sunday in the month lastMon the last Monday in the month Sun>=8 first Sunday on or after the eighth Sun<=25 last Sunday on or before the 25th .fi .in -.5i .sp Names of days of the week may be abbreviated or spelled out in full. Note that there must be no spaces within the .B ON field (or within any other field). .TP .B AT Gives the time of day at which the rule takes affect. Recognized forms include: .nf .in +.5i .sp .ta \w'1:28:13 'u 2 time in hours 2:00 time in hours and minutes 15:00 24-hour format time (for times after noon) 1:28:14 time in hours, minutes, and seconds .fi .in -.5i .sp .TP .B SAVE Gives the amount of time to be added to local standard time when the rule is in effect. This field has the same format as the .B AT field. .TP .B LETTER/S Gives the "variable part" (for example, the 'S' or 'D' in "EST" or "EDT") of time zone abbreviations to be used when this rule is in effect. If this field is .B "-", the variable part is null. .PP A zone line has the form .sp .nf .ti +.5i .ta \w'Zone 'u +\w'Eastern 'u +\w'GMTOFF 'u +\w'MostNA 'u Zone NAME GMTOFF RULES FORMAT .sp For example: .sp .ti +.5i Zone Eastern -5:00 MostNA E%sT .sp .fi The fields that make up a zone line are: .TP .B NAME The name of the time zone. This is the name used in creating the time zone information file for the zone. .TP .B GMTOFF The amount of time to add to GMT to get standard time in this zone. This field has the same format as the .B AT and .B SAVE fields of rule lines; begin the field with a minus sign if time must be subtracted from GMT. .TP .B RULES The name of the rule(s) that apply in the time zone. If this field contains .B "-" then standard time always applies in the time zone. .TP .B FORMAT The format for time zone abbreviations in this time zone. The pairs of characters .B "%s" is used to show where the "variable part" of the time zone abbreviation goes. .PP A link line has the form .sp .nf .ti +.5i .ta \w'Link 'u +\w'LINK-FROM 'u Link LINK-FROM LINK-TO .sp For example: .sp .ti +.5i Link Eastern EST5EDT .sp .fi The .B LINK-FROM field should appear as the .B NAME field in some zone line; the .B LINK-TO field is used as an alternate name for that zone. .PP Lines may appear in any order in the input. .SH EXAMPLE [Since a sample time zone file appears in the shell archive, this section has been omitted.] .SH FILES /etc/tzdir standard directory used for created files .SH "SEE ALSO" settz(3), tzfile(5) .. @(#)tzcomp.8 1.4 End of tzcomp.8 echo tzinfo 1>&2 cat >tzinfo <<'End of tzinfo' # @(#)tzinfo 1.5 # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule MostNA 1969 1973 - Apr lastSun 2:00 1:00 D Rule MostNA 1969 1973 - Oct lastSun 2:00 0 S Rule MostNA 1974 only - Jan 6 2:00 1:00 D Rule MostNA 1974 only - Nov 24 2:00 0 S Rule MostNA 1975 only - Feb 23 2:00 1:00 D Rule MostNA 1975 only - Oct 26 2:00 0 S Rule MostNA 1976 2037 - Apr lastSun 2:00 1:00 D Rule MostNA 1976 2037 - Oct lastSun 2:00 0 S # Almost surely wrong: # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Oz-Eur 1969 1973 - Apr lastSun 2:00 1:00 S Rule Oz-Eur 1969 1973 - Oct lastSun 2:00 0 - Rule Oz-Eur 1974 only - Jan 6 2:00 1:00 S Rule Oz-Eur 1974 only - Nov 24 2:00 0 - Rule Oz-Eur 1975 only - Feb 23 2:00 1:00 S Rule Oz-Eur 1975 only - Oct 26 2:00 0 - Rule Oz-Eur 1976 2037 - Apr lastSun 2:00 1:00 S Rule Oz-Eur 1976 2037 - Oct lastSun 2:00 0 - # New names # Zone NAME GMTOFF RULES FORMAT Zone Atlantic -4:00 MostNA A%sT Zone Eastern -5:00 MostNA E%sT Zone Central -6:00 MostNA C%sT Zone Mountain -7:00 MostNA M%sT Zone Pacific -8:00 MostNA P%sT Zone Yukon -9:00 MostNA Y%sT Zone Hawaiian -10:00 MostNA H%sT Zone Newfoundland -3:30 - NST Zone Japan 9:00 - JST Zone WET 0 Oz-Eur WE%sT Zone MET 1 Oz-Eur ME%sT Zone EET 2 Oz-Eur EE%sT Zone AEST 10:00 Oz-Eur AES%sT Zone ACST 9:30 Oz-Eur ACS%sT Zone AWST 8:00 - AWST # No Daylight Saving here? # # A settz("") uses the code's built-in GMT without going to disk to get # the information. Still, we want things to work if somebody does a # settz("GMT"), so. . . # Zone GMT 0 - GMT # Old names # Link LINK-FROM LINK-TO Link Eastern EST5EDT Link Central CST6CDT Link Mountain MST7MDT Link Pacific PST8PDT # "Pacific Presidential Election Time" is being contemplated in Congress # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Twilite 1969 1973 - Apr lastSun 2:00 1:00 D Rule Twilite 1969 1973 - Oct lastSun 2:00 0 S Rule Twilite 1974 only - Jan 6 2:00 1:00 D Rule Twilite 1974 only - Nov 24 2:00 0 S Rule Twilite 1975 only - Feb 23 2:00 1:00 D Rule Twilite 1975 only - Oct 26 2:00 0 S Rule Twilite 1976 2037 - Apr lastSun 2:00 1:00 D Rule Twilite 1976 1987 - Oct lastSun 2:00 0 S Rule Twilite 1988 2037 uspres Oct lastSun 2:00 1:00 PE Rule Twilite 1988 2037 uspres Nov Sun>=7 2:00 0 S Rule Twilite 1988 2037 nonpres Oct lastSun 2:00 0 S # Zone NAME GMTOFF RULES FORMAT Zone New-Pacific -8:00 Twilite P%sT # Next really belongs in a separate file Link Eastern localtime End of tzinfo exit -- UUCP: ..decvax!seismo!elsie!ado ARPA: elsie!...@seismo.ARPA DEC, VAX and Elsie are Digital Equipment and Borden trademarks Volume-Number: Volume 6, Number 32
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!decvax!decwrl!amdcad!lll-crg!caip!ut-sally!std-unix From: std-u...@ut-sally.UUCP Newsgroups: mod.std.unix Subject: RFC.001 Timezone Proposal Message-ID: <5354@ut-sally.UUCP> Date: Thu, 17-Jul-86 19:10:14 EDT Article-I.D.: ut-sally.5354 Posted: Thu Jul 17 19:10:14 1986 Date-Received: Fri, 18-Jul-86 03:50:33 EDT Organization: IEEE 1003 Portable Operating System for Computer Environments Committee Lines: 64 Approved: j...@sally.UUCP RFC.001 Proposal Form, 18 April 1986, submitted by John S. Quarterman. Time Zone Proposal based on work by Robert Elz and Arthur Olsen. Add 4.5.3 and 4.5.4 to the standard and perhaps also document Arthur Olsen's implementation in an Appendix. 4.5.3 Set Local Time Conversion Function: settz() 4.5.3.1 Synopsis int settz(p) char *p; 4.5.3.2 Description The settz() function determines the conversion from GMT of the local times returned by localtime() and ctime(). When called with a null pointer argument (p==0), settz shall select the appropriate local time conversion for the location of the host machine on which the call is executed. When called with a null string (p!=0 && *p=='\0'), settz shall select no conversion for localtime, making localtime() and gmtime() equivalent and ctime() and asctime(gmtime()) equivalent. When called with a non-null string (p!=0 && *p!='\0'), settz may set the conversion according to that string. The format of the string and the conversions it may specify are implementation specific. If an implementation accepts non-null string arguments to settz, the implementation should allow users to define their own conversions rather than restricting conversions to a standard set. If settz is called with a string for which the implementation can not find a conversion, settz shall return -1, but the conversion it sets is implementation defined and may be one of GMT, the executing machine's local time, or local time for the area where the implementation was performed. 4.5.3.3 Returns Upon successful completion, settz() returns 0, otherwise -1. 4.5.4 Get Local Time Functions: localtime(), ctime() 4.5.4.1 Synopsis [ as in X3J11 ] 4.5.4.2 Description [ as in X3J11, plus: ] The local time conversion is specified by a call on settz(). If localtime() or ctime() is called and settz() has not been called since the last exec(), the localtime() or ctime() call shall call settz(getenv("TZ")) before performing the local time conversion. The local time conversion should be accurate for all times from the base time of the time() function up to the time the call is made. Future times should be converted as accurately as possible with available political information. Daylight savings time should be taken into account in both cases. 4.5.4.3 Returns [as in X3J11 ] 4.5.4.4 Errors [as in X3J11 ] Volume-Number: Volume 6, Number 33
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!caip!ut-sally!std-unix From: std-u...@ut-sally.UUCP (Moderator, John Quarterman) Newsgroups: mod.std.unix Subject: Re: RFC.001 Timezone Interface Message-ID: <5369@ut-sally.UUCP> Date: Sat, 19-Jul-86 13:36:06 EDT Article-I.D.: ut-sally.5369 Posted: Sat Jul 19 13:36:06 1986 Date-Received: Sun, 20-Jul-86 06:20:46 EDT Organization: IEEE 1003 Portable Operating System for Computer Environments Committee Lines: 97 Approved: j...@sally.UUCP In-Reply-To: <5352@ut-sally.UUCP> From: ll-xn!s3sun!sdcsvax!ncr-sd!gr...@topaz.UUCP Date: Fri, 18 Jul 86 15:47:39 PDT Organization: NCR Corporation, Rancho Bernardo Some comments about the timezone proposal to be submitted to P1003. This is mostly nitpicking, but there are some loose ends that such a proposal will need to specify. I will comment from Elz's text; the text of the proposal to P1003 follows this wording closely. In article <5...@ut-sally.UUCP> Robert Elz writes: >localtime: converts the time_t "*t" to a "struct tm" representing >the given time adjusted to represent some local time difference. >"local time" will be specified by a call to "settz", if no such >call has preceded the call to localtime(), localtime() will call >"settz(getenv("TZ"));". ........ Note that this implies that there must be some way for the implementation to tell (a) if settz has been previously called, and presumably, (b) what value was provided by settz. This information should be part of the interface. It is easy to imagine a utility logging subroutine that would want to use the local time when inserting log entries without disturbing other time-display calculations (the user might be running in a different time zone), so this logging subroutine will need to be able to set and potentially reset the time zone information. [ Perhaps. The assumption is that a process will either use the same variety of localtime throughout, or that it will explicitly set the kind it wants with settz before using localtime. That still leaves the question of how localtime knows settz has been used previously, but as long as it does, it's not clear that an application writer needs to know how it's done. -mod ] >If settz is called with an unrecognisable argument, the effect >is implementation defined. (Users might expect any of three >"reasonable"? actions could be taken here -- use GMT, use local time, >or use local time in the area where the implementation was performed). Since I have been bitten too many times by having the default time zone be that of the implementers, I feel that option three is unreasonable. Presumably, since an attempt was made to set the time zone to a non-local value, using GMT as a canonical non-local time zone is probably reasonable (for everybody except those in England, of course -- perhaps it should be called UCT when in this mode so as not to use the same abbreviation). [ This is an example of something you'll find throughout 1003.1: an attempt to not outlaw existing behavior of existing systems. If option three were not included (ugly as it is), I doubt the committee would be able to reach consensus on including settz. -mod ] >What's missing: So far here there is no mention of the "timezone name". >None of the standard mechanisms is really adequate here. ...... >Arthur Olson's scheme causes "localtime" to set a global variable >"tz_abbr" to the correct string name for the timezone just used. I propose an extension of the System V mechanism. That interface defines "extern char *tzname[2]" for the time zone names and has a field in the tm struct (tm_isdst) that is non-zero if daylight savings is in effect; i.e., the current timezone name is tzname[tm.tm_isdst != 0]. I propose that the standard add "extern char *tzname[]" (note that the length is not specified; the bound would be implementation-defined) and have wording that says that tzname[tm.tm_isdst] is the name of the relevant timezone. Since the current System V implementation only sets tm_isdst to zero or one, this is actually backward compatible. (In fact, I just looked through our System V sources for uses of tzname; most of the uses are of the latter form rather than the former, so this proposal is even more compatible than it looks.) >....[problems simulating BSDs "timezone()" function] - one might be to >retain "timezone" but not require that it be capable of returning >anything except the zone name corresponding to the last call of >localtime() ....... With the above proposal, "timezone()" would return values selected from the tzname array if the time zone was one covered by the last settz(), or otherwise return a string of the form "+-hhmm". This function probably should not be part of the standard, since it is primarily present for backward compatibility. If it is present, it should be depreciated so that it can go away in the future. And while we're on backward compatibility, the SysV function tzset() could be defined as "if(timezone_not_set) settz(getenv("TZ");" to be compatible with the way it currently works; again, if this function is defined, its usage should be depreciated. [ I don't think tzset is in the standard, but that's a useful implementation note. -mod ] System V also defines external variables for the current timezone and daylight savings rule. Are there any programs that actually use these? Should they be part of the interface as well? (Or some equivalent functionality?) -- -- Greg Noel, NCR Rancho Bernardo G...@ncr-sd.UUCP or G...@nosc.ARPA Volume-Number: Volume 6, Number 34
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!decvax!yale!husc6!ut-sally!std-unix From: std-u...@ut-sally.UUCP (Moderator, John Quarterman) Newsgroups: mod.std.unix Subject: Re: RFC.001 Timezone Interface Message-ID: <5382@ut-sally.UUCP> Date: Mon, 21-Jul-86 09:46:02 EDT Article-I.D.: ut-sally.5382 Posted: Mon Jul 21 09:46:02 1986 Date-Received: Mon, 21-Jul-86 21:02:14 EDT Organization: IEEE 1003 Portable Operating System for Computer Environments Committee Lines: 23 Approved: j...@sally.UUCP In-Reply-To: <5369@ut-sally.UUCP> Date: Mon, 21 Jul 86 01:23:29 edt From: im4u!caip!m...@cbosgd.ATT.COM (Mark Horton) Organization: AT&T Bell Laboratories, Columbus >System V also defines external variables for the current timezone and daylight >savings rule. Are there any programs that actually use these? Should they be >part of the interface as well? (Or some equivalent functionality?) Yes, there's an important use. If you're generating an RFC 822 compatible >Date: line, you need to know the local offset from GMT or the time zone name. You can't just plug in the time zone name, because only the names in the USA are allowed by 822, and if you try to extend that to the rest of the world, you run into ambiguities. In general, you can't assume that someone in an arbitrary location in the world will understand your local name for your time zone. So you have to generate a zone like "+hhmm". One might even claim that, in a zone like Japan, asking for the time zone name should return "+0900" rather than "JST". Probably not, but it's a thought. Mark Volume-Number: Volume 6, Number 35
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!caip!im4u!ut-sally!std-unix From: std-u...@ut-sally.UUCP (Moderator, John Quarterman) Newsgroups: mod.std.unix Subject: Re: RFC.001 Timezone Interface Message-ID: <5387@ut-sally.UUCP> Date: Tue, 22-Jul-86 21:00:55 EDT Article-I.D.: ut-sally.5387 Posted: Tue Jul 22 21:00:55 1986 Date-Received: Wed, 23-Jul-86 08:47:23 EDT Organization: IEEE 1003 Portable Operating System for Computer Environments Committee Lines: 177 Approved: j...@sally.UUCP Date: 23 Jul 86 08:38:34 +1000 (Wed) From: Robert Elz <munnari!...@SEISMO.CSS.GOV> I have (more than) a few comments about some comments about the timezone proposal. [ There's only one comment from the moderator in this article: discussions are very useful, but to get in the standard it needs exact wording. In other words, anyone wanting changes to the proposal form I posted should supply *exact wording changes*. (An alternative would be to submit a complete new proposal.) -mod ] Quotes until stated otherwise are from Greg Noel (ncr-sd!greg)... > Note that this implies that there must be some way for the implementation > to tell (a) if settz has been previously called, and presumably, (b) what > value was provided by settz. I agree, I hadn't considered this. However, its essential that when there's an interface that sets some static state, there be some means to determine the current value of that state - I've been frustrated so many times by hardware with write only registers that I should have seen this myself. But, now after thinking about it for a few days, I'm not sure how it should be done. There would seem to be two quite different, but equally possible approaches, though neither is ideal. One would be for settz() to save the arg string it is called with, and for a new function (gettz() ?) to return it. That sounds simple enough, but unfortunately might be something of an implementation headache. The string can be of arbitrary length, so no static buffer in settz to hold it would be appropriate. That means that settz would be required to malloc() memory to hold this string, just on the off chance that it might be needed later (which it very rarely will be). I really have very limited enthusiasm for making library routines at this level get involved in storage allocation. (Settz could presumably just remember the pointer to the string it was passed, and gettz could return that pointer - but this has so many potential problems that its not worth contemplating). The (an?) other implementation would be to define two functions, perhaps savetz() and restoretz(). Savetz would return (in some manner not important here) the internal state that settz has established. restoretz() would restablish that state as settz would have left it. This might be handled by having savetz copy the state into a buffer supplied by the caller, or perhaps it would malloc some memory and return a pointer to that. Malloc here is not a problem, as its only being done by the specific request of the user, its not a hidden side effect. Of the two schemes, I think I prefer the latter, but I would appreciate comments from readers, either to the list if you (and the moderator) think there will be general interest in your comments, or in mail to me. I think John Quarterman (our friendly moderator) answered your query about the "implementors timezone" default possibility for settz. I might just add that I can't imagine how a new implementation could conceivably make that choice - its just there to cope with old code. To implement this proposal, an implementation must be able to obtain both the hosts local time, and GMT without being told anything externally (ie: by being handed either (char *)0 or "" resp). If it can do that, it can also easily choose one of those as the default in cases where it is given an invalid argument. > I propose an extension of the System V mechanism.... I propose > that the standard add "extern char *tzname[]" ... and have wording > that says that tzname[tm.tm_isdst] is the name of the relevant timezone. Yes, this would be nice, unfortunately it can't work. You are assuming that there is just one non-DST timezone name, and all the others are names of various DST types. This just isn't true in general. Since tm_isdst must be zero for any tm_* that is not a daylight savings time representation, your scheme would allow only one non-DST zone name. A new field could be added to struct tm to be the tzname[] index, but this would break all existing code that wants zone names, and if we're going to do that, perhaps we should look and see exactly when a zone name is required. To the best of my knowledge, the only sensible use of a timezone name is to associate with a human visible date/time representation. Since these things aren't unique, they are useless to hold any internal representation of a timezone. In effect, that means that the only time a timezone name will (should) ever be needed is when a date/time has been converted for external output, and the zone that will be wanted will be the zone of the time that was just converted. If anyone has a counter-example, I would be pleased to learn of it. Given this assumption, it seems that all that's needed is for localtime() to arrange that the relevant zone name is available somehow, either in an external "char *" variable, or as the return value of a function. For Sys V compatability, and implementation could provide char *tzname[2] and set both pointers to the zone name needed? Is anyone aware of any code this would break? For v7 conpatability, the timezone(3) function could be made to ignore its args, and just return the selected zone name. > And while we're on backward compatibility, the SysV function tzset() could > be defined as "if(timezone_not_set) settz(getenv("TZ");" to be compatible > with the way it currently works; again, if this function is defined, its > usage should be depreciated. Certainly, AT&T, and anyone who wants to be compatible with current Sys V programs should provide tzset as indicated, and should make it, as far as possible (note "tzname" difficulties as mentioned above) compatible with the functionality of the Sys V tzset. However, including definitions in the standard, along with wording like "don't use this, it shouldn't be here, and is going away" seems ludicrous to me. > System V also defines external variables for the current timezone and daylight > savings rule. I don't know about daylight savings rule, I don't remember that one, and my Sys V manual seems to have walked away, but "timezone" is impossible to get right. There's no doubt that its intended usage is that tzset() should set this variable to the local standard timezone offset. But this assumes that there is such a thing as a "standard timezone offset" that applies for all times in the zone. This just isn't true.. Eg: a couple of years ago now, Singapore (I think) changed its timezone so it would be the same as Malaysia. What value should be put in "timezone" for Singapore? The correct answer depends on what time is being converted - if its a time before the switch, then it should be their old zone, for one after, it should be the new zone. That is, its not a constant! Following quotes are from Mark Horton (cbosgd!mark)... [about uses of "timezone"] > Yes, there's an important use. If you're generating an RFC 822 compatible > Date: line, you need to know the local offset from GMT... Nonsense! This isn't a use of the Sys V "timezone" variable at all. That's not the information it provides. What you need for an RFC822 Date: line is the numeric offset of the time that was converted. That's not necessarily the hosts local time zone (which is what "timezone" is supposed to contain). And even in cases where host local time is what is wanted, "timezone" isn't it - as the local time converted might have been a daylight savings time. To turn the Sys V "timezone" into the correct thing in that case, one would need to imbed some nonsense like "if (tm->tm_isdst) timezone += 60;" (or maybe -= 60, and maybe the number is 3600, details are irrelevant. And no, I wouldn't really modify "timezone"). Getting rid of assumptions about things like DST being one hour forwards is one of the major aims of all this. What *is* needed is a method to obtain the timezone offset that is appropriate for a given time. That's a different problem entirely. An interface to provide this information might be valuable. If there isn't such an interface, then the offset can easily calculated in a portable manner by applications (see my posting to mod.sources, vol 6 issue 12 "datediffs" for an example of doing approximately this). > One might even claim that, in a zone like Japan, asking for the time zone > name should return "+0900" rather than "JST". Probably not, but it's > a thought. This was, of course, a joke (and not even a good one). Robert Elz seismo!munnari!kre kre%munnari...@seismo.css.gov Volume-Number: Volume 6, Number 36