Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.1+some 2/3/84; site dual.UUCP
Path: utzoo!watmath!clyde!floyd!harpo!seismo!ut-sally!mordor!dual!fair
From: f...@dual.UUCP
Newsgroups: net.unix-wizards,net.bugs.usg
Subject: TZ Rationalization Requested
Message-ID: <341@dual.UUCP>
Date: Fri, 9-Mar-84 19:57:41 EST
Article-I.D.: dual.341
Posted: Fri Mar  9 19:57:41 1984
Date-Received: Sat, 10-Mar-84 12:54:08 EST
Distribution: net
Organization: Dual Systems, Berkeley, CA
Lines: 52

I have a bone to pick with the folks who decided to change the way
UNIX keeps track of the timezone in System III and System V. For those
fortunate enough to be using 4BSD or V7, I will explain.

In Version 7, the timezone was kept in a variable in the kernel, in the
form of the number of minutes westward of GMT. There was also a flag that
indicated whether daylight savings time applies in the timezone.

In System III, this changed to keep the hours westward of GMT, along with
the DST flag in an environment variable, dubbed `TZ'. The following
string is in my TZ variable:

		PST8PDT

This says that my timezone is called `PST', and I'm 8 hours west of GMT,
and that daylight savings applies, and is called `PDT'.

The fact that it is in an environment variable now makes life difficult
for programs that are spawned from /etc/init (e.g. getty), and the SA's
have to remember to add TZ=PST8PDT; export TZ to the top of their /etc/rc
file. Login has to be fixed to either get it from some file, or try and
find it in the enviroment passed to it (where it won't be, since init
doesn't have an environment, and init spawns getty).

But the two most objectionable `features' of this implementation are

	1) To make the TZ `take', you have to call tzset();
	2) The default timezone is EST.

The effect of #2 is that you don't notice you didn't do #1, when you're
in New Jersey. So there's lots of UNIX software that's broken, when you
move it west (or east!) of EST. The end result is that I (and others, no
doubt) have spent, and will spend lots of time cleaning up after this
re-implementation of timekeeping.

Now, the thing *I* want to know is:

	Why the guys at USG decided to do things this way?

The most credible argument I have heard is that if you're logged
into a system in another timezone, you want your mail stamped with the
timezone you're in, and when you fire up `date', it will give the time for
your timezone, rather than the computer's. Or at least you want this
capability.

Has anyone else heard a better reason to do it this way?

	Erik E. Fair

	dual!f...@BERKELEY.ARPA
	{ihnp4,ucbvax,cbosgd,decwrl,amd70,fortune,zehntel}!dual!fair
	Dual Systems Corporation, Berkeley, California

Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.1a 12/4/83; site rlgvax.UUCP
Path: utzoo!watmath!clyde!burl!ulysses!harpo!seismo!rlgvax!guy
From: g...@rlgvax.UUCP (Guy Harris)
Newsgroups: net.unix-wizards,net.bugs.usg
Subject: Re: TZ Rationalization Requested
Message-ID: <1795@rlgvax.UUCP>
Date: Fri, 9-Mar-84 21:35:26 EST
Article-I.D.: rlgvax.1795
Posted: Fri Mar  9 21:35:26 1984
Date-Received: Sat, 10-Mar-84 14:17:12 EST
References: <341@dual.UUCP>
Distribution: net
Organization: CCI Office Systems Group, Reston, VA
Lines: 96

The question was "why do USG UNIX systems get the timezone information
from an environment variable TZ, which is only read if you remember to
call "tzset()", while it comes from a system call in V7 and descendants?"
and "has anyone else heard a better reason to do it this way?"

Well, the only reason I can think of to do it this way, other than the
ability you mentioned to set the time zone on a per-session basis, is the
ability to change the time zone without doing a system generation.

I don't know that this is a better reason to do it this way; on the other hand,
what you've given is a reason to do it a better way.

Suggested way - thanks to Microsoft, who did it at least partially this way
on their S3-base Xenix, which also keeps around the old V7 system call
"ftime" to get it from the kernel.

1) GET RID OF THE REQUIREMENT TO EXPLICITLY CALL "tzset"!  If the extra
CPU cycles spent asking for the timezone on every call to "ctime" bothers
you, set a static flag once you've called "tzset", and only call it from
within "ctime" (and "localtime" and the like) if the flag is zero.  There's
not much point in calling "tzset" twice in a process, anyway, considering
it requires a bit of contortion to change the processes' environment from
within the process (chase down "environ" for the "TZ=" entry and replace it).
"tzset" can still be left around; you may just want the timezone and DST flag
values, and you may not want to make a system call (for reasons of portability
to S5 and previous USG versions).

2) Have "tzset" make the system call if it doesn't find TZ in the environment,
instead of defaulting to EST.  Keep the old V7 table of time zone names, and
have it search that table after the system call to find the names.

In effect, you're merging the V7 and USG code, and keeping the USG call
interface (which is downward (upward? whatever) compatible with V6, but not
compatible with V7.  Too bad they couldn't make up their mind...).  If TZ
is not set, things don't break, they just get the time zone from a nice
central source.  TZ is only set if somebody explictly wants to override it.
As for the question of doing sysgens, that's a red herring.  In USG UNIX, you
have to do sysgens *anyway*, in order to set kernel parameters and (this is
the key point) *the system's network node name*.  So it's not practical to
just build one binary and stick it on several machines without change
*anyway*.  I don't know if anybody builds a common kernel and then patches
the "utsname" structure *ex post facto* (we do), but one could patch a timezone
information structure in the same way.

Or, if that's too kludgy, take a leaf from Berkeley's book - specifically,
the book labelled "UNIX Programmer's Manual, 4.2 Berkeley Software
Distribution, Virtual VAX-11 Version" and the leaf labelled "GETTIMEOFDAY(2)".
The "gettimeofday" system call takes two pointers to structures as arguments,
and fills those structures in: a structure containing the time of day (a
longword of seconds and a longword of microseconds) and a structure containing
the timezone information (offset in minutes west of Greewich and daylight
savings time flag). "settimeofday" takes two pointers to similar structures as
arguments; the contents of the first structure sets the system time, and if
the pointer to the second structure is non-NULL its contents set the timezone
information and DST flag (the fact that the latter pointer may be NULL and
causes the system to leave the timezone information alone is undocumented -
add another one to the long list of undocumented and useful and worthy-of-
official-support-and-documentation features in UNIX, both Bell and Berkeley).
They did the same thing with the host name, by the way; "gethostname" and
"sethostname" system calls exist.

The requirement that an environment variable be set in order for the system
to understand time zones sucks.  The person who made it a requirement obviously
never thought that somebody would actually put something in the "shell"
field in the password file, so obviously you can set TZ in "/etc/profile"
(which gets executed by the USG Bourne shell, when run as a login shell,
just before your ".profile" - a good idea, by the way) and it'll be set for
everybody except for stuff run from "/etc/rc" - set it there, and you're home
free, right?  WRONG!  We frequently set up people who run our office automation
software with that system as their login shell, and the top-level shell
of that software doesn't know "/etc/profile" from Adam.  There *are* two
ways of fixing this:

1) make their "login shell" a shell file (yes, believe it or not, this is
supported by the V7, 4.xBSD, S3, and S5 "login program) which sets TZ and
runs the program in question.  This means, of course, that when you install
a system it's *one more place* where you have to remember to change TZ if
it's in a different time zone...

2) fix "login" so that it adds things like HOME to the environment passed
to it, rather than creating a new environment *ab initio*, and make your
lines in "/etc/inittab" look like

	2:h0:c:env TERM=vt100 TZ=PST8PDT /etc/getty ttyh0 d

which is the solution we chose, as it permits us to put TERM into the
environment automatically as well; the authors of a lot of the UNIX code work
for an organization that places heavy emphasis on dial-up use of UNIX
(the reasons for this should be obvious when you consider the main source
of revenue for that organization :-)), where setting TERM automatically
is usually useless, but most of us work at sane places with 9600 baud or
faster hardwired terminals, and port "/dev/ttyh0" is going to be a VT100
unless and until somebody moves the VT100.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10 5/3/83; site cbosgd.UUCP
Path: utzoo!watmath!clyde!burl!ulysses!mhuxl!cbosgd!mark
From: m...@cbosgd.UUCP (Mark Horton)
Newsgroups: net.unix-wizards,net.bugs.usg
Subject: Re: TZ Rationalization Requested
Message-ID: <1081@cbosgd.UUCP>
Date: Sat, 10-Mar-84 02:02:25 EST
Article-I.D.: cbosgd.1081
Posted: Sat Mar 10 02:02:25 1984
Date-Received: Sat, 10-Mar-84 14:34:16 EST
References: <341@dual.UUCP>
Organization: AT&T Bell Laboratories, Columbus
Lines: 11

An interesting side effect of the environment style method of determining
the time zone is that, since any user can set his environment, it's
easy to forge your time zone.  What good does that do, you ask?  Well,
if your system has restrictions on what time of day certain programs
(e.g. games) can be run, claiming to be in a funny time zone can
get around them.  (Although just chmodding /usr/games from crontab
isn't subject to this.)  If UUCP is only allowed to dial another
system at certain times (presumably when the rates are lower),
you can trick it into calling anyway.  Finally, since you get to make
up the name as well as offset of the time zone, you can use the real
name and a fake offset, in order to, say, backdate mail you send.

Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10 5/3/83; site cbosgd.UUCP
Path: utzoo!watmath!clyde!burl!ulysses!mhuxl!ihnp4!cbosgd!mark
From: m...@cbosgd.UUCP (Mark Horton)
Newsgroups: net.unix-wizards,net.bugs.usg
Subject: Re: TZ Rationalization Requested
Message-ID: <1084@cbosgd.UUCP>
Date: Sat, 10-Mar-84 16:41:44 EST
Article-I.D.: cbosgd.1084
Posted: Sat Mar 10 16:41:44 1984
Date-Received: Sun, 11-Mar-84 06:53:43 EST
References: <341@dual.UUCP>, <1795@rlgvax.UUCP>
Organization: AT&T Bell Laboratories, Columbus
Lines: 5

By the way, what do people in Newfoundland and Central Australia,
who are on half-hour time zones, do about their time zones when
they run USG UNIX?  I shudder to think about Saudi Arabia.
In V7, the zone is specified in minutes west of GMT.  In USG,
it's in hours.

Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.1 6/24/83; site brl-vgr.ARPA
Path: utzoo!watmath!clyde!burl!ulysses!harpo!seismo!brl-vgr!gwyn
From: g...@brl-vgr.ARPA (Doug Gwyn )
Newsgroups: net.unix-wizards,net.bugs.usg
Subject: Re: TZ Rationalization Requested
Message-ID: <2359@brl-vgr.ARPA>
Date: Sat, 10-Mar-84 21:46:37 EST
Article-I.D.: brl-vgr.2359
Posted: Sat Mar 10 21:46:37 1984
Date-Received: Sun, 11-Mar-84 06:55:45 EST
References: <341@dual.UUCP>, <1795@rlgvax.UUCP>
Organization: Ballistics Research Lab
Lines: 17

?  I thought the convention on USG UNIXes was to set TZ in one of the
rc files so that it would be in everyone's environment.

I don't know why Berkeley didn't make the timezone offset returned by
gettimeofday() be in seconds instead of minutes (minor quibble).

Note to recipients of the BRL UNIX System V emulation for 4.2BSD:
John Quarterman pointed out the consquences of a lack of TZ in 4.2BSD
users' environments, and I have fixed ctime.c/tzset() to get the zone
from the kernel via _gettimeofday() if TZ is not in the environment.
This is a simple patch, but let me know if you need the updated source.

MY complaint about all this is that the Berkeley kernel does not
supply the timezone name (CST, CDT, etc.).  Otherwise their system call
seems like$!good idea, provided that TZ in the environment is allowed
to override the system timezone for those rare cases where that is
useful.

Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.1a 12/4/83; site rlgvax.UUCP
Path: utzoo!watmath!clyde!burl!ulysses!harpo!seismo!rlgvax!guy
From: g...@rlgvax.UUCP (Guy Harris)
Newsgroups: net.unix-wizards,net.bugs.usg
Subject: Re: TZ Rationalization Requested
Message-ID: <1802@rlgvax.UUCP>
Date: Sun, 11-Mar-84 00:48:12 EST
Article-I.D.: rlgvax.1802
Posted: Sun Mar 11 00:48:12 1984
Date-Received: Sun, 11-Mar-84 07:07:51 EST
References: <341@dual.UUCP>, <1795@rlgvax.UUCP> <2359@brl-vgr.ARPA>
Organization: CCI Office Systems Group, Reston, VA
Lines: 25

> ?  I thought the convention on USG UNIXes was to set TZ in one of the
> rc files so that it would be in everyone's environment.

Unfortunately, setting it in an rc file doesn't do any good for processes
run directly out of /etc/inittab, like "getty".

> MY complaint about all this is that the Berkeley kernel does not
> supply the timezone name (CST, CDT, etc.).  Otherwise their system call
> seems like a good idea, provided that TZ in the environment is allowed
> to override the system timezone for those rare cases where that is
> useful.

In the US I don't think this is a problem, as the offset from GMT uniquely
identifies the time zone (although there may be weird exceptions), but
the V7 scheme of having an offset-to-timezone-name table may break elsewhere;
I remember seeing a claim in net.mail.somethingorother that European
countries give the same zone different names because they want the name to
make sense in their native languages.  If this is the case, the V7 scheme
is OK in the US but the name would have to be supplied independently, such
as with a system call.  I guess the implementors, who lived in the US,
figured that the time zone name was redundant information and should be
computed from the offset.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.1a 12/4/83; site rlgvax.UUCP
Path: utzoo!watmath!clyde!burl!ulysses!mhuxl!eagle!harpo!seismo!rlgvax!guy
From: g...@rlgvax.UUCP (Guy Harris)
Newsgroups: net.unix-wizards,net.bugs.usg
Subject: Re: TZ Rationalization Requested
Message-ID: <1805@rlgvax.UUCP>
Date: Sun, 11-Mar-84 02:46:33 EST
Article-I.D.: rlgvax.1805
Posted: Sun Mar 11 02:46:33 1984
Date-Received: Mon, 12-Mar-84 04:58:41 EST
References: <341@dual.UUCP>, <1795@rlgvax.UUCP> <1084@cbosgd.UUCP>
Organization: CCI Office Systems Group, Reston, VA
Lines: 42

Remember, there is a comment in "ctime.c" that says "This routine does not
work in Saudi Arabia which runs on Solar Time", so the Saudis are screwed by
V6, V7, and USG.

The problem with half-hour time zones could be solved if the "tzset()"
routine were fixed to accept a syntax like

	ZST6:30ZDT

to specify that Zombie Standard Time was 6 hours and 30 minutes off from GMT.
(No offense meant to the people in any such time zone, or to zombies. :-))
And here's the fix (untested, but it looks trivial):

After the line

		timezone = ((long)(n * 60)) * 60;

in "tzset()" in "ctime.c", stick the code:

		if (*p == ':') {
			p++;
			while(*p >= '0' && *p <= '9')
				n = (n * 10) + *p++ - '0';
			if(sign)
				n = -n;
			timezone += n*60;
		}

(This is for the System V "ctime.c", but it's probably the same fix for the
System III "ctime.c".)

Note, BTW, that "timezone" is represented in seconds in USG UNIX; I doubt
that the extra resolution is useful, *but* it saves extra multiplications by
60.  (How to further enhance "tzset" to permit

	WST6:30:05WDT

to specify Wacko Standard Time to be 6 hours, 30 minutes, and 5 seconds off
GMT is left as an exercise for the reader. :-))

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.1 6/24/83; site hou3c.UUCP
Path: utzoo!watmath!clyde!burl!hou3c!ka
From: k...@hou3c.UUCP (Kenneth Almquist)
Newsgroups: net.unix-wizards,net.bugs.usg
Subject: Re: TZ Rationalization Requested
Message-ID: <408@hou3c.UUCP>
Date: Tue, 13-Mar-84 14:06:41 EST
Article-I.D.: hou3c.408
Posted: Tue Mar 13 14:06:41 1984
Date-Received: Wed, 14-Mar-84 08:16:33 EST
References: <341@dual.UUCP>
Distribution: net
Organization: Bell Labs, Holmdel, NJ
Lines: 25

One reason for using the TZ variable is to avoid the need for yet
another system call.

Eric raises two objections to the use of TZ:

	The fact that it is in an environment variable now makes
	life difficult for programs that are spawned from /etc/init
	(e.g. getty), and the SA's have to remember to add
	TZ=PST8PDT; export TZ to the top of their /etc/rc file.
	Login has to be fixed to either get it from some file, or
	try and find it in the enviroment passed to it (where it
	won't be, since init doesn't have an environment, and init
	spawns getty).

I have never found this to be a problem, although I can see that it
might be for some people.  As delivered, getty and login do not need
to know the time zone.  It would probably be better to have TZ set
by init.

	To make the TZ `take', you have to call tzset();

If this is true in System III (and it's not in System V; I just looked
at the source), the fix should be trivial.  Just add a call to tzset()
at the beginning of the localtime routine.
					Kenneth Almquist