🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c
Article #5419

Re: The type of time_t

#5419
From: Tim Pozar
Date: Tue, 01 Nov 1988 00:17
143 lines
5120 bytes
    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
Technical Details
Message-ID: <5803@hoptoad.uucp>
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!unisoft!hoptoad!pozar
References: <442@grand.UUCP> <8700@smoke.BRL.MIL> <6964@cdis-1.uucp> <9816@haddock.ima.isc.com> <1988Oct22.230215.19411@utzoo.uucp> <Oct.24.11.33.01.1988.12179@ron.rutgers.edu> <10005@haddock.ima.isc.com>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!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> <Oct.24.11.33.01.1988.12179@ron.rutgers.edu> <10005@haddock.ima.isc.com>
Reply-To: pozar@hoptoad.UUCP (Tim Pozar)
Organization: Syncstream/Widget Systems (San Francisco)
Lines: 143