karl@haddock.ima.isc.com (Karl Heuer) (10/21/88)
In article <6964@cdis-1.uucp> tanner@cdis-1.uucp (Dr. T. Andrews) writes: >If any of the aforementioned evil lasts until 2038, we've got fun. >That's when our present time_t should become negative. There's nothing to prevent time_t from being typedef'd to unsigned long int, which would double the range. (Also, it would not surprise me if by 2038 there were no serious machines with only 32 bits in a long int.) Of course, if you want to implement time_t with more precision than one tick per second, then doomsday arrives much sooner. >A more clever interface might arrange a slightly different way to indicate an >error: > int mktime(struct tm *tmptr, time_t *t) >returns 0 if it worked (*t filled in), or -1 if it fails. That would have worked for mktime(), which was apparently an invention of the Committee, but the time() function also needs to be able to indicate failure (if the system has no clock). Unfortunately time() as commonly implemented returns a time_t as its value in addition to (optionally) storing it via the argument, so the obvious solution (int time(time_t *), result 0 or -1) would break existing code. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint Followups to comp.std.c.
decot@hpisod2.HP.COM (Dave Decot) (10/22/88)
> There's nothing to prevent time_t from being typedef'd to unsigned long int, > which would double the range. (Also, it would not surprise me if by 2038 > there were no serious machines with only 32 bits in a long int.) In fact, the last time I checked, time_t was erquired to be an "arithmetic" type, not necessarily an integral type. So, you could use double to implement it, correct? Dave
henry@utzoo.uucp (Henry Spencer) (10/23/88)
In article <9816@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes: >There's nothing to prevent time_t from being typedef'd to unsigned long int, >which would double the range... Unfortunately, it would probably break a significant number of programs that think time_t is signed. Those programs are arguably broken already, but some degree of pragmatism is necessary in such matters. -- The meek can have the Earth; | Henry Spencer at U of Toronto Zoology the rest of us have other plans.|uunet!attcan!utzoo!henry henry@zoo.toronto.edu
flaps@dgp.toronto.edu (Alan J Rosenthal) (10/23/88)
karl@haddock.ima.isc.com (Karl Heuer) writes: >>There's nothing to prevent time_t from being typedef'd to unsigned long int, >>which would double the range... henry@utzoo.uucp (Henry Spencer) writes: >Unfortunately, it would probably break a significant number of programs that >think time_t is signed. Those programs are arguably broken already, but some >degree of pragmatism is necessary in such matters. Is it possible to assume that time_t is signed without assuming it's either int or long (or char)? I can't see how, and if it's not then Karl's change above wouldn't break any more programs than changing time_t between int and long would. (It is true that a cast to long sort of assumes that the value cast is signed, but in the case of time_t I don't see what you want to do with that value except cast it back to time_t, which makes the cast to long rather pointless. Or if you want to printf the number, well ansi printf's %lu format takes a long, not an unsigned long, anyway, so the cast to long is the correct way to print unsigned longs as well as longs.) ajr -- #define __STDC__ 0
ron@ron.rutgers.edu (Ron Natalie) (10/24/88)
Frankly, life is going to be screwed up before the time bits are fixed because many programs that compute dates think that 2000 is not a leap year. We can always follow the TOPS-10 convention of moving the Epoch. -Ron
karl@haddock.ima.isc.com (Karl Heuer) (10/25/88)
In article <Oct.24.11.33.01.1988.12179@ron.rutgers.edu> ron@ron.rutgers.edu (Ron Natalie) writes: >Frankly, life is going to be screwed up before the time bits are fixed because >many programs that compute dates think that 2000 is not a leap year. I doubt that there are many such programs, since the naive algorithm (y%4==0) happens to agree with the correct one until 2100 (the century and quadri- century corrections cancel each other out in 2000). The problem that's likely to occur in 2000 has to do with two-digit notation for the year; now *that's* going to screw up a lot of existing code. (The `date' command doesn't even *have* a notation to set the date beyond 1999!) Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
mcgrath@tully.Berkeley.EDU.berkeley.edu (Roland McGrath) (10/27/88)
["The type of time_t (was: struct tm -> time_t converter wanted)"] - henry@utzoo.uucp (Henry Spencer):
) In article <9816@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes:
) >There's nothing to prevent time_t from being typedef'd to unsigned long int,
) >which would double the range...
)
) Unfortunately, it would probably break a significant number of programs that
) think time_t is signed. Those programs are arguably broken already, but some
) degree of pragmatism is necessary in such matters.
With the Epoch defined as it is for Unix (Jan 1 00:00:00, 1970), it is
desireable to have a signed `time_t' type. Although I didn't, the world
did exist before 1970.
Roland McGrath
roland@wheaties.ai.mit.edu, mit-eddie!wheaties.ai.mit.edu!roland
guy@auspex.UUCP (Guy Harris) (10/28/88)
>With the Epoch defined as it is for Unix (Jan 1 00:00:00, 1970), it is >desireable to have a signed `time_t' type. Although I didn't, the world >did exist before 1970. The world also existed before whatever 1902 or so; having "time_t" be signed will help only to a limited degree. If you want a type to be used for time-stamping arbitrary events in the past and the future, "time_t" on UNIX systems isn't going to be it no matter whether it's signed or unsigned, unless you make it bigger than 32 bits (in which case signedness will probably be irrelevant). However, "time_t" is generally used to time-stamp events occurring on a UNIX machine, and there were relatively few of them around before 1970....
friedl@vsi.COM (Stephen J. Friedl) (10/28/88)
Somebody writes: >With the Epoch defined as it is for Unix (Jan 1 00:00:00, 1970), it is >desireable to have a signed `time_t' type. Although I didn't, the world >did exist before 1970. In article <334@auspex.UUCP>, guy@auspex.UUCP (Guy Harris) writes: > > The world also existed before whatever 1902 or so; having "time_t" be So, Guy, you were born in 1902? :-) :-) :-) -- Steve Friedl V-Systems, Inc. +1 714 545 6442 3B2-kind-of-guy friedl@vsi.com {backbones}!vsi.com!friedl attmail!vsi!friedl ----Nancy Reagan on 120MB SCSI cartridge tape: "Just say *now*"----
flaps@dgp.toronto.edu (Alan J Rosenthal) (10/28/88)
roland@wheaties.ai.mit.edu (Roland McGrath) writes: >With the Epoch defined as it is for Unix (Jan 1 00:00:00, 1970), it is >desirable to have a signed `time_t' type. Although I didn't, the world >did exist before 1970. First of all, negative time_t values don't mean time before time zero. This is confirmed by the return value (time_t)(-1) from mktime() which means "not a time I can represent", rather than 31 Dec 1969 23:59:59 GMT. Most of all, time_t is for representing events that happen while the system is running: the current time, the scheduled time of events in the future (e.g. alarms, sleeps), and the time of events in the past (e.g. file timestamps). It is not sufficient, nor should it be, for representing the times of all events in human history and future; a more sophisticated, and larger, representation is required for that. So any zero-date in the past is ok, because a file need not be able to have a timestamp predating the writing of the operating system it is available on. ajr -- #define __STDC__ 0
pozar@hoptoad.uucp (Tim Pozar) (11/01/88)
Tom sent me this the other day... Might be helpful for the algorythms... Tim --- /* Tom Jennings Fido Software 27 Oct 88 These two functions convert MSDOS stored time and date (16 bit integer each for time and date) to the 32 bit "number of seconds since 1970" used by Zmodem. long dos2sec(dostime,dosdate) unsigned dostime; /* MSDOS time */ unsigned dosdate; /* MSDOS date */ Converts the MSDOS time and date (as stored in the structure from an MSDOS search first/next call or a get-file-time call) to the long integer to put into a Zmodem ZFILE packet. It fails (overflows) somewhere around the turn of the century (32 bits isn't long enough!) long sec2dos(sec70) long sec70; Converts the "seconds since 1970" from Zmodem to a long imteger that contains the MSDOS time and date within it; the high 16 bits are MSDOS date, and the low 16 bits are MSDOS time, each as used by MSDOS set-file- time functions. (They are stored packed as that's how my internal routines handle them.) long stonum(s,base) char *s; unsigned base; A simple "atoi()" like function that converts a string of ASCII digits into a long integer; it stops when it finds a non-digit. The conversion is done modulo (base), ie. 10 for decimal numbers, 8 for octal numbers. (Zmodem file size is stored decimal; time as octal. Both are long.) */ /* Convert MSDOS packed time to long seconds since 1970. (Basic conversion derived from code supplied by Stuart Gathman.) */ long dos2sec(dostime,dosdate) unsigned dostime,dosdate; { int y,dayofyear; long time; #define Uyear ((dosdate >> 9) & 0x3f) /* as stored in search */ #define Umonth ((dosdate >> 5) & 0x0f) /* first/next structure */ #define Uday (dosdate & 0x1f) /* or get file time DOS call */ #define Uhour ((dostime >> 11) & 0x1f) #define Uminute ((dostime >> 5) & 0x1f) #define Usecond ((dostime & 0x1f) << 1) /* (kept as 2 second resolution) */ y= Uyear + 80; /* DOS date base is 1980 */ dayofyear= Uday + ((Umonth * 275) / 9) - 30;/* day of year, */ if (Umonth > 2) { /* handle leapyears */ --dayofyear; /* Feb 28/29, 1 Mar */ if (Uyear % 4) --dayofyear; } time= dayofyear + ((long)(y - 1) * 1461L) / 4; /* day of century */ time -= 25203L; /* minus days 1900 - 1970 */ time *= 86400L; /* second of century */ time += (long)Uhour * 3600L; /* add seconds this day, */ time += Uminute * 60; time += Usecond; /* cprintf("dos2sec: %02d/%02d/%02d %02d:%02d:%02d=%lu\r\n",y,Umonth,Uday,Uhour,Uminute,Usecond,time); */ return(time); } /* Convert seconds since 1970 to MSDOS packed time and date. The DOS date is in the upper two bytes, time in the lower. (Same as passed in a TELINK block.) (Basic conversion derived from code supplied by Stuart Gathman.) */ long sec2dos(sec70) long sec70; { long time; int dayofyear,leapyear; int year,month,day; time= sec70 % 86400L; /* time only */ sec70 /= 86400L; /* date only */ sec70 += 25203L; /* add days 1900 - 1970 */ leapyear= 2; year= ((sec70 - (sec70 / 1461) + 364) / 365); /* make year, */ dayofyear= sec70 - ((long)(year - 1) * 1461) / 4;/* day in current year */ if (year % 4 == 0) leapyear= 1; if (dayofyear > 59 && ((dayofyear > 60) || (leapyear == 2))) dayofyear += leapyear; month= (269 + (dayofyear * 9)) / 275; day= dayofyear + 30 - ((275 * month) / 9); /* cprintf("\r\nsec2dos: %lu == %02d/%02d/%02d %02d:%02d:%02d\r\n",x,year,month,day,time / 3600L,(time % 3600L) / 60L,(time % 3600L) % 60L); */ sec70= 0L; sec70 |= ((year - 80) & 0x3f) << 9; /* pack the date (starts 1980) */ sec70 |= (month & 0x0f) << 5; /* into lower 16 bits */ sec70 |= day & 0x1f; sec70 <<= 16L; /* shift to upper 16 bits */ sec70 |= ((time / 3600L) & 0x1f) << 11; /* then pack the time */ time %= 3600L; /* hours, */ sec70 |= ((time / 60L) & 0x3f) << 5; /* minutes, */ sec70 |= ((time % 60L) & 0x1f) >> 1; /* seconds. */ return(sec70); } /* Convert a string of ASCII digits to a long number, in the specified base. Works only for bases 1 - 10 (mainly: dec. and octal) */ long stonum(s,base) char *s; int base; { int i; long n; n= 0L; while ((*s >= '0') && (*s <= '9')) n= (base * n) + (*s++ - '0'); return(n); } -- ...sun!hoptoad!\ Tim Pozar >fidogate!pozar Fido: 1:125/406 ...lll-winken!/ PaBell: (415) 788-3904 USNail: KKSF / 77 Maiden Lane / San Francisco CA 94108
guy@auspex.UUCP (Guy Harris) (11/02/88)
> Tom sent me this the other day... Might be helpful for > the algorythms... At least for OSes that store local time rather than GMT. OSes that store GMT, such as UNIX, need more than that.
scs@athena.mit.edu (Steve Summit) (11/12/88)
In article <8810281846.AA20611@champlain.dgp.toronto.edu> flaps@dgp.toronto.edu (Alan J Rosenthal) writes: >So any zero-date in the past >is ok, because a file need not be able to have a timestamp predating the >writing of the operating system it is available on. This is, I'll admit, a nit, but I'd suggest otherwise. I pay a lot of attention to file modification times, and I often transfer files between different operating systems (Unix, VMS, MS-DOS) while attempting to preserve modification times (using tar and the like). This means that I have a problem if I take a file last modified in 1979 to an MS-DOS system, because DOS's epoch is 1980. (The problem is theoretically even worse when moving files from VMS, which has an epoch of 1865 or so.) Not much of a problem in practice, but it's something to think about. (And, of course, it's insoluble.) Steve Summit scs@adam.pika.mit.edu
lum@bat.cis.ohio-state.edu (Lum Johnson) (11/15/88)
In article <7917@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve Summit) writes: >In article <8810281846.AA20611@champlain.dgp.toronto.edu> flaps@dgp.toronto.edu (Alan J Rosenthal) writes: >> >>So any zero-date in the past is ok, because a file need not be able to have >>a timestamp predating the writing of the operating system it is available on. > >... I'd suggest otherwise. I pay a lot of attention to file modification >times, and I often transfer files between different operating systems (Unix, >VMS, MS-DOS) while attempting to preserve modification times (using tar and >the like). This means that I have a problem if I take a file last modified >in 1979 to an MS-DOS system, because DOS's epoch is 1980. (The problem is >theoretically even worse when moving files from VMS, which has an epoch of >1865 or so.) Not much of a problem in practice, but it's something to think >about. (And, of course, it's insoluble.) Good point - this might be important or useful information. The epoch you're referring to is probably 0000 GMT 17-Nov-1858, the same as for pdp-10 monitors with which I am familiar. The date was chosen by someone at The Smithsonian Institution if I recall correctly; I no longer remember the significance, but it was probably when the Gregorian calendar was adopted by some official group or major government. Our local EXEC has been modified to change the write date when a file is copied so as to avoid the file migration policy. This annoys me so much that I have another version of the EXEC without this modification for my use. (In fact, I have several EXECs with and without various nasty "features".) -=- -- Lum Johnson lum@osu-20.ircc.ohio-state.edu lum@tut.cis.ohio-state.edu "You got it kid -- the large print giveth and the small print taketh away." -------