POSE proposal for TZ

Moderator, John Quarterman std-unix at ut-sally.UUCP
Fri Feb 14 22:12:31 AEST 1986


Date: Fri, 14 Feb 86 00:51:16 PST
>From: sun!guy at seismo.UUCP (Guy Harris)

>      The major points of the proposal are:
>    
>            1. There is a world-readable, superuser-modifiable file
>               named "/etc/TIMEZONE" that describes the per-system
>               timezone information and Daylight Saving Time rules.

Too specific.  The standard should not give all the implementation details.
Giving this much detail merely constrains an implementation to use the
particular technique specified, even if it isn't the appropriate technique
to use (on a V7 or 4BSD system, for instance, fetching it from the kernel is
more appropriate, since it's already there).

>            3. The TZ variable has 2 required parts (and an optional 3rd):
>    
>               A = standard abbreviation for the timezone as used by the
>    	        local area
>    	            A :== [A-Z][A-Z]*
>               B = plus or minus difference in minutes from Universal Time,
>               plus for those locations east of GMT, minus for west
>                   B :== [+-][0-9][0-9][0-9]
>               C = standard abbreviation for the timezone as used by the
>    	        local area when Daylight Saving Time is in effect.  This
>	        part of TZ may be absent if DST is not used.
>                   C :== [A-Z][A-Z]*

Unnecessarily incompatible with System V, which specifies the offset from
Universal Time in hours.  (It also requires you to multiply an offset in
hours by 60, which is much better done by a computer.)  See below for a
better way of specifying offsets which aren't an integral number of hours.

>            4. The DST variable has 0 or 2 parts in the string.  It has
>               zero if no Daylight Saving Time is observed or 2, when DST
>               starts and ends, for those places that do observe it.

Not sufficient.  The routines that convert between GMT and local time can be
given a time not in the current year; if the time is in a year prior to the
current one, these routines must still be able to convert it, and must
therefore know the rules for all years prior to the current one.  (The
4.2BSD source indicates that the rules for 1970, 1971, and 1972 in Australia
were all rather different; 1970 had no daylight savings time, 1971 had it
from October 31 to the end of the year, 1972 had it from January 1 to
February 27 and October 31 to December 31, and all subsequent years had it
January 1 to March 7 and October 31 to December 31.  In the US, of course,
we had the infamous "nixonflag" for 1974 and 1975....)  For times in the
future, of course, it will have to rely on a projection (if it could handle
times in the future exactly, I'd put it to work on Sun's stock price...).
    
>            7. TZ and DST are put into the environment of each user
>               when the user logs in.
>
>            8. Those utilities that strip off environment information
>               can obtain TZ and DST values by reading "/etc/TIMEZONE".

What puts TZ and DST into the environment of each user?  If it's not done by
"login", then every program which is used as a login shell must do it.  A
LOT of UNIX systems have many users who log in to a specific application,
which may never run the shell.  As such, it should be done by "login", which
makes the Bourne shell syntax unhelpful.

And what about utilities not run by a logged-in user?  Must they look in
"/etc/TIMEZONE"?  If so, do they have to do their own parsing?  There is
already a routine in System V called "tzset()", which sets the global
variables "timezone" and "daylight".  In vanilla S5, it just scans the TZ
environment variable (which means you have to go through contortions to get
that variable set).  In systems which have a source for time zone
information other than TZ, they can scan TZ if present and non-null, and use
that source otherwise.  In your proposal, "tzset()" should scan that file.
However, we have now eliminated the need for any program to look at
"/etc/TIMEZONE" directly - they should let "tzset()" do it for them.

The trouble is that there are several ways of storing the time zone
information, other than in the TZ environment variable.  V7 stored it,
in effect, in "/unix"; you specified it when you built your kernel.  4.2BSD
also stores it there (in "/vmunix", actually); you can specify it when you
build your kernel, but you can also specify it with the "settimeofday"
system call.  A system running on a machine with an EEPROM might store the
time zone there, and either read it out when the machine is booted or make
it readable by user programs.  A "hosted" system (i.e., a system which
provides a P1003-compatible environment on top of an existing operating
system) might be able to get it out of the host operating system.  A table
containing this operation might be mapped into the address space of all
processes in any of a number of ways, depending on the memory model of the
OS and the whims of the OS's designers.

It's inappropriate to commit to something as specific as "/etc/TIMEZONE";
"tzset()" should be specified as fetching the appropriate information and
setting the "timezone", "daylight", and "tzname" external variables (System
V-style) and also arranging, somehow, for the daylight savings time rules to
be set up.

The only copy of the X3J11 C standard draft I can get my hands on right now
is an old one.  It lists "asctime", "ctime", "gmtime", and "localtime" as
being like their UNIX versions, but doesn't list "tzset", "timezone",
"daylight", or "tzname".  Presumably, it considers them to be part of the
operating system (or environment) rather than the C language/library.  (Have
they been added in later drafts?)  If they haven't been added in later
drafts, I propose that P1003 adopt the System V versions, as specified in
the System V Interface Definition, with the following change:

change

	...the external variable "daylight" is non-zero only if the
	standard U.S.A. Daylight Savings Time conversion should be
	applied.  The program compensates for the peculiarities
	of this conversion in 1974 and 1975; if necessary, a table
	for these years can be extended.

	If an environment variable named TZ is present, "asctime" uses the
	contents of the variable to override the default time zone.  The
	value of TZ must be a three-letter time zone name, followed
	by an optional minus sign (for zones east of Greenwich) and
	a series of digits representing the difference between local time
	and Greenwich Mean Time in hours; this is followed by an
	optional three-letter name for a daylight time zone.

to

	...the external variable "daylight" is non-zero only if the
	standard Daylight Savings Time conversion for the current time
	zone, if any, should be applied.  The external variable "tzname"
	contains pointers to the name of the time zone when daylight
	savings time is	not in effect and when it is in effect in its
	first and second members, respectively.

	The default time zone is settable by the system administrator,
	and is usually the time zone that the majority of the system's
	users are in.  "tzset" normally sets the variables "timezone",
	"daylight", and "tzname" to the values for the default time zone.
	If an environment variable named TZ is present, "tzset" sets the
	variables "timezone", "daylight", and "tzname" from the value
	of this environment variable.  The value of TZ must either be
	of the form "GMT+hh[:mm]", or "GMT-hh[:mm]", specifying an
	unnamed time zone "hh" hours and "mm" minutes ahead of or behind
	Universal Time (if "mm" is not present, it is assumed to be
	zero), or a zone name followed by an optional minus sign (for
	zones east of Greenwich) and a specification of the form "hh[:mm]"
	specifying the difference between local time and Universal Time
	in hours and minutes; this is followed by an optional name for the
	time zone when Daylight Savings Time is in effect.  A time zone name
	must not contain any digits and must not contain the characters "+",
	"-", or ":".  If an unnamed zone is specified, Daylight Savings
	time rules are considered not to apply, and the time zone name is
	assumed to be the value of the TZ environment variable.

I include the "GMT+/-hh:mm" specification on the assumption that there are
unnamed time zones; if this is not so, this part may be deleted.  Note that
unlike the System V TZ value, this permits time zone names to be longer or
shorter than 3 characters.  It also permits fractional-hour time zone
offsets; it uses a different syntax than the one described in the "FUTURE
DIRECTIONS" section, because that section doesn't indicate whether the
time zone offset must be four digits (which would mean that EST5EDT would no
longer be valid) or not (which would mean that OLT7ODT would be ambiguous -
is Out to Lunch Time 7 hours away from GMT or 7 minutes?).  The proposed
syntax is an upward-compatible extension of the current syntax, which the
syntax in the "FUTURE DIRECTIONS" section is not.

If TZ is not set, "tzset" will presumably get the Daylight Savings Time
rules from some standard place (where it gets them from is an implementation
detail which does not belong in P1003).  If TZ is set, there should be some
indication of where it gets the DST rules from.  It can either get them from
some "standard" database of rules, or from an environment variable (either
from additional data at the end of TZ, or from DST), or both (i.e., if the
rules aren't specified in an environment variable, it uses the time zone
specified in TZ to look up the rules in the standard database).

Volume-Number: Volume 5, Number 50



More information about the Mod.std.unix mailing list