[tz] Java & Rearguard

Guy Harris guy at alum.mit.edu
Mon Jun 3 21:19:30 UTC 2019

On Jun 3, 2019, at 9:44 AM, Fred Gleason <fredg at paravelsystems.com> wrote:
> On Sun, 2019-06-02 at 18:10 +0100, Stephen Colebourne wrote:
>> As I, and others, have said, I don't believe there is any appetite to
>> change the meaning of DST in Java - the pain would be far too great
>> with no or negative benefits.
> Perhaps it would be helpful to review what happened in the POSIX world
> in a similar situation. The man page for gettimeofday(3) on Linux has
> contained this narrative for as long as I can remember (mid/late
> 1990s):
> *** snip snip ***
>       Traditionally, the fields of struct timeval were of type long.
>       The tz_dsttime field has never been used under Linux.
>       Thus,  the  following is purely of historic interest.
>       On old systems, the field tz_dsttime contains a symbolic 
>       constant (values are given below) that indicates in which part 
>       of the year  Daylight Saving  Time is in force.  (Note: this 
>       value is constant throughout the year: it does not indicate
>       that DST is in force,  it  just  selects  an algorithm.) 
>       The  daylight  saving time algorithms defined are as follows:
>           DST_NONE     /* not on DST */
>           DST_USA      /* USA style DST */
>           DST_AUST     /* Australian style DST */
>           DST_WET      /* Western European DST */
>           DST_MET      /* Middle European DST */
>           DST_EET      /* Eastern European DST */
>           DST_CAN      /* Canada */
>           DST_GB       /* Great Britain and Eire */
>           DST_RUM      /* Romania */
>           DST_TUR      /* Turkey */
>           DST_AUSTALT  /* Australian style with shift in 1986 */

Whoever wrote that part of the Linux man page used a definition of "old systems" that means "systems starting with 4.2BSD" rather than, for example, "systems starting with Seventh Edition UNIX".  The "tz_dstime" page was introduced in 4.2BSD; it was not present in V7 UNIX, or in any of the System Roman Numeral versions of UNIX from AT&T.

> I find it significant that POSIX apparently ended up ditching an entire
> API element in favor of adding a model capabale of handling the full
> complexities of civil timekeeping (as they were understood at the
> time); a move which surely must have caused heartburn for many POSIX-
> based applications in use at that time.

V7 UNIX had a system that, to handle the full complexities of civil timekeeping in any given location, would require a source code change to ctime.c:


and a recompile of the C library and all programs using ctime()/localtime() to handle any location in which the rules for when DST begins and ends don't match those of the US in effect from 1976 to 1986, or in which the time change is anything other than "turn the clocks forward by one hour when it begins and back one hour when it ends".  The standard-time offset from UTC could be obtained with an ftime() system call; changing it required recompiling the kernel, installing the new kernel, and rebooting.

4.2BSD improved this slightly.  It allowed the standard-time offset from UTC to be set with a system call, so that no kernel recompile and reboot was required, and allowed selection from a small set of Daylight Saving Time rules, with the rule also settable with a system call.  The rules for each set, however, were still compiled into ctime.c, so changing the rules would still require changing ctime.c and recompiling the C library and all programs using ctime()/localtime(), and adding a new rule set would, in addition to that, involve changing the header that defines the values for the types of DST rules, adding a new type for use by ctime.c.

Meanwhile, at least according to a manual of System III vintage (it appears to have been an internal AT&T manual for "UNIX 3.0" rather than the documentation issued for the public release of UNIX 3.0/System III, but it's probably close enough):


As per ctime(3), TZ could be set to specify the abbreviations for standard and Daylight Saving Time, as well as the offset from UTC of standard time in hours, but could not specify non-hour offsets or DST rules or change offsets other than the standard US ones (see previous comment about "change ctime.c and do a bunch of recompiling").

A purported System V Release 1 manual:


says pretty much the same thing in ctime(3), as does a purported SVR2 manual:


and a purported SVR3 manual:


An SVR3.1 manual for the 32-bit x86 port:


first shows a TZ syntax capable of handling non-US rules; SVR3.1 came out sometime in the late 1980's, probably 1987-1988.

That syntax was probably the basis of the POSIX syntax; the first POSIX release came out in 1988.

The "Olson database" effort from which came the tzdb and the tzdb code was started sometime in 1986:


so it predated the release of the first POSIX specification.  The POSIX committee didn't, I think, want to standardize the tzdb, so as not to overly constrain implementations, but they allowed TZ to begin with a colon, followed by implementation-dependent text, to allow alternative ways of specifying the time zone, and I think that was done primary if not entirely to allow tzdb IDs to be provided.

By 1988, whatever BSD-based systems had the time zone stuff in gettimeofday()/settimeofday() had, I think, switched to using the tzdb code and data, so that the 4.2BSD-style way of specifying the time zone was provided only for backwards compatibility.  So it was 1) less capable than the SVR3.1 scheme and 2) not really being used any more, so there wasn't any reason for POSIX to standardize on it.

I don't remember whether tzcode ever paid any attention to the 4.2BSD-style time zone setting on systems where it was available, e.g. mapping the values for various regions to tzdb IDs and using that ID.  It may not have.

Eventually, SVR4 also picked up tzcode and tzdata via the Sun/AT&T work.

I'm not sure what complexities, if any, the transition from the 4.2BSD scheme, on systems providing it, to the tzdb scheme added.  I forget when I added the initial support for POSIX-style TZ settings in tzcode; that pretty much made support for POSIX-style TZ settings Just Work on systems using tzcode.  I don't know whether any systems supported the 4.2BSD scheme and didn't end up picking up the tzcode.

Systems *not* using the 4.2BSD scheme just had to pick up later SV code to get support for the SVR3.1 scheme; I don't know whether SVR3.2 added support for whatever in the POSIX scheme wasn't already in the SVR3.1 scheme, but, if so, picking up that code would have added POSIX compatibility for TZ, and the vendors could also have added that themselves.

More information about the tz mailing list