64-bit time_t must go--this is non-negotiable

Robert Elz kre at munnari.OZ.AU
Fri Jun 18 07:02:08 UTC 2004


    Date:        Thu, 17 Jun 2004 12:56:47 -0700
    From:        Paul Eggert <eggert at CS.UCLA.EDU>
    Message-ID:  <87d63yj6v4.fsf at penguin.cs.ucla.edu>

  | "Olson, Arthur David (NIH/NCI)" <olsona at dc37a.nci.nih.gov> writes:
  | 
  | > time_t has been a 32-bit entity since day one of UNIX,
  | 
  | No, actually, it was a 'long' entity.

No, it wasn't.

  | The very first UNIX ran on the
  | PDP-7, which was an 18-bit host, so I suspect (though I can't easily
  | check this :-) that time_t was a 36-bit quantity on the very first
  | UNIX host.

It probably was, but it wasn't long.   Back in those days there was
no C to have the modern concept of "long" at all, and even when C
existed initially, there was no "typedef" to create new types (like time_t).
That's all relatively recent additions (well, 7th edition, 1979 or so).

In the earliest  unix, time() operated on a int [2] array (which is
why time() and all the other time related funcs, has their time args
passed  as a pointer - having time() return the value as well is another
recent addition).

The first unix on 32 bit processors actually had times represented
as 64 bits, as that kept on using int[2] except with 32 bit ints
(this was the University of Wollongong (Richard Miller) port of
v6 unix to the Interdata (Perkin Elmer later) systems (which preceded
the Bell Labs Interdata port which much influenced v7).

When that switched to v7 it went back to 32 bits (using "long").

  | > The historic precedent in the UNIX realm is the addition of the
  | > "lseek" system call once files got larger
  | 
  | That predated C's typedef feature.  A closer precedent is what
  | happened to lseek when file offsets grew from 32 to 64 bits.  By this
  | time, people were supposed to use "off_t", and "off_t" grew from 32 to
  | 64 bits without changing the name of "lseek".  (The story is a bit
  | more complicated than this, but that's the general idea.)  The changes
  | to time/ctime/etc. are similar.

yes, though ado still has a point, one still does need to handle existing
applications that know time_t as a 32 but quantity.   While the name of
lseek wasn't changed (as known by the C compiler) to move from 32 to 64
bit offsets, the actual system call certainly was changed (the 32 bit
version still exists on any architecture old enough to have had
applications from when lseek took 32 bit offsets).

Other changes of a similar nature have actually had source visible
modifications - which is the better approach for any particular change
requires careful thought and study.   Certainly it isn't correct to
simply cite the precedent of some other (different) change, and act
as if that was sufficient justification for any new change.

Personally, at the minute, I have no idea whether making time_t a 64
bit type, or introducing a new type for bigger times is the better
approach.   If FreeBSD are trying it in some limited sense, that's
great, and will provide feedback on how well things work (though doing
FreeeBSD sparc64 probably isn't a great test for existing applications...)

I'm also by no means convinced that a 64 bit time_t that is just twice
as many bits, bit otherwise unchanged from, our current 32 bit time_t
is a rational thing to do.   I can't imagine wanting to know about
times that stretch from 1970 to 1970 + 2.6 * 10^11, that's just absurd.
When more bits are added, the time base should probably be moved (a long
way), and lots of the extra bits (say 20 or the added 32) should
be used for extra precision, rather than extra years.   Put the 0 value
at about 10000 years info the future (say year 10000 itself), allow + and -
time values, and 44 bits of year values stretches from before year -270K
to almost year 300K, which is plenty of range, with microsecond precision.

But this is just one possibility - not necessarily a good one, but
certainly better than 2^64 bits of seconds.

kre



More information about the tz mailing list