dave@moncam.co.uk (Speaker-To-Animals) (02/06/90)
I am writing an implementation of the ANSI C date and time functions. Unfortunately, I don't have a copy of the standard itself yet, so I'm working from K&R2. time_t is described as a scalar type. difftime() returns the difference between two times as a double. If time_t represents a time in centiseconds (say), a 32-bit unsigned value will cover a period of a year or so. Are times more precise than 1 second only possible in implementations with greater than 32 bit integers? Since time() returns -1 if the time is not available, it doesn't seem possible to define time_t as an array of integers. -- Dave Allen Monotype International ADG Science Park Milton Road Cambridge CB4 4FQ England dave@moncam.UUCP
henry@utzoo.uucp (Henry Spencer) (02/10/90)
In article <DAVE.90Feb6112502@marvin.moncam.co.uk> dave@moncam.co.uk (Speaker-To-Animals) writes: >... time_t is described as a scalar type. difftime() returns >the difference between two times as a double. If time_t represents a time >in centiseconds (say), a 32-bit unsigned value will cover a period of a year >or so. Are times more precise than 1 second only possible in implementations >with greater than 32 bit integers? Since time() returns -1 if the time is >not available, it doesn't seem possible to define time_t as an array of >integers. Unless this changed since the Oct 88 draft, time_t is not constrained to be a scalar type, only to be an arithmetic type. That is, it could be floating-point. It also might be some implementation-specific type like "long long int". Furthermore, there is no guarantee that you can do useful arithmetic on time_t values; the encoding of the time in a time_t is explicitly unspecified, the only constraint being that `(time_t) -1' must not be a valid time. The inability to do arithmetic is the reason why difftime() exists. You are correct that a 32-bit integer isn't practical for time resolutions less than one second; indeed, it's increasingly marginal even at that resolution, since the times "go negative" less than fifty years from now. I'd say time_t is going to have to go to 64 bits (or perhaps to floating point) fairly soon. -- SVR4: every feature you ever | Henry Spencer at U of Toronto Zoology wanted, and plenty you didn't.| uunet!attcan!utzoo!henry henry@zoo.toronto.edu
karl@haddock.ima.isc.com (Karl Heuer) (02/10/90)
In article <1990Feb9.183316.24925@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: >In article <DAVE.90Feb6112502@marvin.moncam.co.uk> dave@moncam.co.uk (Speaker-To-Animals) writes: >>Are times more precise than 1 second only possible in implementations >>with greater than 32 bit integers? > >... [time_t] could be floating-point. >You are correct that a 32-bit integer isn't practical for time resolutions >less than one second; indeed, it's increasingly marginal even at that >resolution, since the times "go negative" less than fifty years from now. >I'd say time_t is going to have to go to 64 bits (or perhaps to floating >point) fairly soon. Not necessarily. An unsigned long would give us 32 bits (worst case) instead of the current 31; this would push the "overflow date" into the 22nd century. The need for sub-second resolution is the dominant requirement here. As far as I can see, the only reason that it has to be arithmetic at all is so that time() can return (time_t)-1 to flag an error. This is rather bizarre, since existing Unix implementations never return an error from time(); unfortunately, because existing code uses "t = time((time_t *)0);" in addition to the equivalent "(void)time(&t);" to read the time, it appears that there wasn't much choice. I wonder if maybe "time()" should have been deprecated in favor of a "gettime()" function that would only return 0 (filling in its argument like time() does) or -1. Karl W. Z. Heuer (karl@ima.ima.isc.com or harvard!ima!karl), The Walking Lint
flee@shire.cs.psu.edu (Felix Lee) (02/10/90)
Are you allowed to compare time_ts without using difftime()? Or should I write "difftime(now, then) < 0" instead of "now < then"? Can time_t be a pointer (converted to an arithmetic if necessary)? Imagine typedef struct tm * time_t; time() would allocate a new struct tm and return a pointer to it. This is assuming you don't compare time_t values directly and don't try to read or write them. -- Felix Lee flee@shire.cs.psu.edu *!psuvax1!flee
bdm659@csc.anu.oz (02/10/90)
In article <1990Feb9.183316.24925@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes: > > Unless this changed since the Oct 88 draft, time_t is not constrained to > be a scalar type, only to be an arithmetic type. That is, it could be > floating-point. It's the same in the Dec 1988 draft. > It also might be some implementation-specific type like > "long long int". Are you sure about that? Section 3.1.2.5 claims to give a complete list of arithmetic types. Shouldn't we take "arithmetic type" as meaning "one of the types this Standard says are arithmetic types"? I can't find any specific guidelines on this matter in the Standard, though Section 3.3.3.4 of the Rationale has this to say about the size_t type: "The type of sizeof, whatever it is, is published (in the library header <stddef.h>) as size_t, since it is useful for the programmer to be able to refer to this type. This requirement implicitly restricts size_t to be a synonym for an *existing* unsigned integer type, thus quashing any notion that the largest declarable object might be too big to span even with an unsigned long." [my emphasis] Brendan McKay. bdm@anucsd.oz(.au) or bdm659@csc1.anu.oz(.au) terrorist: n. an individual who behaves like a government
henry@utzoo.uucp (Henry Spencer) (02/11/90)
In article <15919@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes: >>[32-bit time_t] times "go negative" less than fifty years from now... > >Not necessarily. An unsigned long would give us 32 bits (worst case) instead >of the current 31; this would push the "overflow date" into the 22nd century. Unfortunately, there's a major backward-compatibility issue here: all the Unix code which assumes that the difference of two time_t values is signed. Yes, that code "really ought to" use difftime() to avoid this, and not doing so limits its portability... but declaring it unportable is one thing, and breaking it even in its native environment is another. I don't think it's worth the trouble for one bit. We need a longer-term solution which also (as Karl points out) addresses the issue of better resolution. >...the only reason that it has to be arithmetic at all is so >that time() can return (time_t)-1 to flag an error. This is rather bizarre, >since existing Unix implementations never return an error from time()... However, non-Unix implementations may have to, if they can't supply a time. -- SVR4: every feature you ever | Henry Spencer at U of Toronto Zoology wanted, and plenty you didn't.| uunet!attcan!utzoo!henry henry@zoo.toronto.edu
henry@utzoo.uucp (Henry Spencer) (02/11/90)
In article <Ccvioy2@cs.psu.edu> flee@shire.cs.psu.edu (Felix Lee) writes: >Are you allowed to compare time_ts without using difftime()? Or >should I write "difftime(now, then) < 0" instead of "now < then"? There is explicitly no guarantee of the internal representation of time_t. Since it is an arithmetic type, you can do direct comparisons... but there is no guarantee that the result will be meaningful. If you want portable comparisons, difftime() is indeed the correct method. >Can time_t be a pointer (converted to an arithmetic if necessary)? >...This is assuming you don't compare time_t values directly and don't >try to read or write them. Unfortunately, there is way too much existing code which assumes that a time_t can be assigned, passed around, etc. A pointer is not an arithmetic type and hence is not a legal time_t type. -- SVR4: every feature you ever | Henry Spencer at U of Toronto Zoology wanted, and plenty you didn't.| uunet!attcan!utzoo!henry henry@zoo.toronto.edu
henry@utzoo.uucp (Henry Spencer) (02/11/90)
In article <1487.25d42437@csc.anu.oz> bdm659@csc.anu.oz writes: >> It also might be some implementation-specific type like >> "long long int". > >Are you sure about that? ... No. Slippery area. -- SVR4: every feature you ever | Henry Spencer at U of Toronto Zoology wanted, and plenty you didn't.| uunet!attcan!utzoo!henry henry@zoo.toronto.edu
gwc@root.co.uk (Geoff Clare) (02/13/90)
In article <15919@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes: >As far as I can see, the only reason that it has to be arithmetic at all is so >that time() can return (time_t)-1 to flag an error. This is rather bizarre, >since existing Unix implementations never return an error from time(); It's needed so that mktime() can return (time_t)-1 to flag an error (for unrepresentable times). -- Geoff Clare, UniSoft Limited, Saunderson House, Hayne Street, London EC1A 9HH gwc@root.co.uk (Dumb mailers: ...!uunet!root.co.uk!gwc) Tel: +44-1-315-6600 (from 6th May 1990): +44-71-315-6600