The type of time_t

Tim Pozar pozar at hoptoad.uucp
Tue Nov 1 10:17:41 AEST 1988


    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



More information about the Comp.std.c mailing list