Path: utzoo!attcan!uunet!unisoft!hoptoad!pozar From: pozar@hoptoad.uucp (Tim Pozar) Newsgroups: comp.std.c Subject: Re: The type of time_t Message-ID: <5803@hoptoad.uucp> Date: 1 Nov 88 00:17:41 GMT References: <442@grand.UUCP> <8700@smoke.BRL.MIL> <6964@cdis-1.uucp> <9816@haddock.ima.isc.com> <1988Oct22.230215.19411@utzoo.uucp> <10005@haddock.ima.isc.com> Reply-To: pozar@hoptoad.UUCP (Tim Pozar) Organization: Syncstream/Widget Systems (San Francisco) Lines: 143 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