dos_compilers/Mix Power C v1/TIME.C
2024-07-01 15:26:34 -07:00

539 lines
15 KiB
C

/* Time and date functions */
/* Copyright (c) Mix Software 1988 */
char *ctime(time)
long time;
{
char *asctime();
struct tm *localtime();
return asctime(localtime(time));
} /* ctime */
size_t strftime(s, maxsize, format, timeptr)
char *s; /* buffer for result */
size_t maxsize; /* maximum size of s */
char *format; /* format string */
struct tm *timeptr; /* time to convert */
{ /* formatted time */
static char *shortday[7] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
static char *longday[7] = {"Sunday","Monday","Tuesday","Wednesday",
"Thursday","Friday","Saturday"};
static char *shortmonth[12] = {"Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec"};
static char *longmonth[12] = {"January","February","March","April",
"May","June","July","August","September",
"October","November","December"};
static char *am_pm[2] = {"AM","PM"};
static int _strput(int, char *, int);
char *asctime();
extern char *tzname[2];
#define put(ch) {if (--length) *s++ = ch; else return 0;}
char ch, *p;
char str[20];
int length = maxsize;
int value;
while (*format != '\0') {
if (*format != '%') put(*format++)
else {
p = str;
memset(p,0,sizeof(str));
switch (*++format) {
case 'a' :
p = shortday[timeptr->tm_wday];
break;
case 'A' :
p = longday[timeptr->tm_wday];
break;
case 'b' :
p = shortmonth[timeptr->tm_mon];
break;
case 'B' :
p = longmonth[timeptr->tm_mon];
break;
case 'c' :
p = asctime(timeptr);
break;
case 'd' :
_asct2dig(timeptr->tm_mday,p);
break;
case 'H' :
_asct2dig(timeptr->tm_hour,p);
break;
case 'I' :
value = timeptr->tm_hour;
if (value > 12) value -= 12;
_asct2dig(value,p);
break;
case 'j' :
case 'J' :
_asct3dig(timeptr->tm_yday,p);
break;
case 'm' :
_asct2dig(timeptr->tm_mon+1,p);
break;
case 'M' :
_asct2dig(timeptr->tm_min,p);
break;
case 'p' :
p = am_pm[timeptr->tm_hour / 12];
break;
case 'S' :
_asct2dig(timeptr->tm_sec,p);
break;
case 'U' :
value = timeptr->tm_wday - (timeptr->tm_yday % 7);
if (value < 0) value += 7; /* week day of Jan 1 */
value = (timeptr->tm_yday + value - 1) / 7;
_asct2dig(value,p);
break;
case 'w' :
*p = timeptr->tm_wday + '0';
break;
case 'W' :
value = timeptr->tm_wday - (timeptr->tm_yday % 7);
if (value < 0) value += 7; /* week day of Jan 1 */
value = (timeptr->tm_yday + value) / 7;
_asct2dig(value,p);
break;
case 'x' :
_asct2dig(timeptr->tm_mon+1,str);
_asct2dig(timeptr->tm_mday,&str[3]);
_asct2dig(timeptr->tm_year % 100,&str[6]);
str[2] = '/';
str[5] = '/';
break;
case 'X' :
_asct2dig(timeptr->tm_hour,str);
_asct2dig(timeptr->tm_min,&str[3]);
_asct2dig(timeptr->tm_sec % 100,&str[6]);
str[2] = ':';
str[5] = ':';
break;
case 'y' :
_asct2dig(timeptr->tm_year % 100,p);
break;
case 'Y' :
_asct2dig(timeptr->tm_year / 100,str);
_asct2dig(timeptr->tm_year % 100,&str[2]);
break;
case 'Z' :
if (timeptr->tm_isdst) p = tzname[1]; else p = tzname[0];
if (p == NULL) p = str;
break;
case '%' :
*p = '%';
break;
} /* switch */
while (*p != '\0') put(*p++)
++format;
} /* '%' */
} /* while */
*s = '\0';
return maxsize - length;
#undef put
} /* strftime */
char *asctime(time)
struct tm *time;
{ /* convert time to a character string */
static char *monthname[13] = {"Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec"};
static char *dayname[7] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
static char timebuf[26];
int yy;
strcpy(timebuf,"www mmm dd hh:mm:ss yyyy\n");
memcpy(timebuf,dayname[time->tm_wday],3);
memcpy(&timebuf[4],monthname[time->tm_mon],3);
_asct2dig(time->tm_mday,&timebuf[8]);
_asct2dig(time->tm_hour,&timebuf[11]);
_asct2dig(time->tm_min,&timebuf[14]);
_asct2dig(time->tm_sec,&timebuf[17]);
yy = time->tm_year < 100 ? 19 : 20;
_asct2dig(yy,&timebuf[20]);
_asct2dig(time->tm_year % 100,&timebuf[22]);
return timebuf;
} /* asctime */
_asct2dig(n, p)
int n;
char *p;
{
*p++ = (n / 10) + '0';
*p = (n % 10) + '0';
}
_asct3dig(n, p)
int n;
char *p;
{
*p++ = (n / 100) + '0';
n = n % 100;
*p++ = (n / 10) + '0';
*p = (n % 10) + '0';
}
time_t mktime(timeptr)
struct tm *timeptr;
{
long _timesec(int, int, int, int, int, int);
struct tm *localtime();
struct tm *_timecvt(time_t);
time_t t;
t = _timesec(timeptr->tm_year+1900, timeptr->tm_mon+1, timeptr->tm_mday,
timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec);
*timeptr = *localtime(&t);
return t;
}
int stime(tp) /* set time */
long *tp;
{
struct tm *t;
union REGS time, date;
t = localtime(tp);
time.h.ah = 0x2d;
time.h.ch = t->tm_hour;
time.h.cl = t->tm_min;
time.h.dh = t->tm_sec;
time.h.dl = 0;
date.h.ah = 0x2b;
date.x.cx = t->tm_year+1900;
date.h.dh = t->tm_mon+1;
date.h.dl = t->tm_mday;
intdos(&date,&date);
intdos(&time,&time);
return 0;
}
struct utimbuf {
time_t actime; /* access time */
time_t modtime; /* modification time */
};
int utime(filename, times)
char *filename;
struct utimbuf *times;
{
extern int _doserrno, errno;
union REGS r;
struct tm *localtime(time_t *), *tptr;
union {
struct ftime time;
struct {
int time;
int date;
} i;
} filetime;
time_t t, time();
int handle;
int status;
if (times == NULL) t = time(NULL); else t = times->modtime;
tptr = localtime(&t);
if (_sys_ad(0x3d00,filename,&handle) != 0)
{ errno = _doserrno; return -1; }
if (tptr->tm_year < 80) filetime.time.ft_year = 0;
else filetime.time.ft_year = tptr->tm_year-80;
filetime.time.ft_month = tptr->tm_mon+1;
filetime.time.ft_day = tptr->tm_mday;
if (tptr->tm_hour < 0) filetime.time.ft_hour = 0;
else filetime.time.ft_hour = tptr->tm_hour;
filetime.time.ft_min = tptr->tm_min;
filetime.time.ft_tsec = tptr->tm_sec >> 1;
r.x.ax = 0x5701;
r.x.bx = handle;
if (_sysabcd(0x5701,handle,filetime.i.time,filetime.i.date,&status) != 0) {
errno = _doserrno;
_sys_ab(0x3e00,handle,&handle);
return -1;
}
_sys_ab(0x3e00,handle,&handle);
return 0;
}
struct tm *gmtime(time)
long *time;
{
struct tm *_timecvt();
return _timecvt(*time);
} /* gmtime */
struct tm *localtime(time)
long *time;
{
extern long timezone;
extern int daylight;
void tzset();
struct tm *_timecvt();
static tzdone = 0;
if (tzdone == 0) {tzset(); tzdone = 1; }
if (daylight) return _timecvt(*time-timezone+3600);
return _timecvt(*time-timezone);
} /* localtime */
void unixtodos(utime, dateptr, timeptr)
long utime;
struct date *dateptr;
struct time *timeptr;
{
extern struct tm *_timecvt();
extern long timezone;
extern int daylight;
struct tm *t;
long localtime;
localtime = utime - timezone;
if (daylight) localtime += 3600l;
t = _timecvt(localtime);
dateptr->da_year = t->tm_year + 1900;
dateptr->da_mon = t->tm_mon+1;
dateptr->da_day = t->tm_mday;
timeptr->ti_hour = t->tm_hour;
timeptr->ti_min = t->tm_min;
timeptr->ti_sec = t->tm_sec;
timeptr->ti_hund = 0;
}
struct tm *_timecvt(time)
long time;
{ /* convert binary time to greenwich mean time */
static struct tm gm;
static int daypermonth[12] = {31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
extern int daylight;
long secs, days;
int years, leaps, dayofyear;
int month = 0;
int *mptr = daypermonth;
days = time / 86400;
years = days/365;
leaps = (years+1) / 4;
dayofyear = days - (long)years * 365 - (long)leaps;
if (dayofyear < 0) {
years--;
dayofyear += 365;
}
gm.tm_yday = dayofyear;
gm.tm_year = years+70;
if ((years % 4) == 2) daypermonth[1] = 29; else daypermonth[1] = 28;
while (dayofyear > *mptr) {
++month;
dayofyear -= *mptr++;
}
gm.tm_mon = month;
gm.tm_mday = dayofyear+1;
gm.tm_wday = (days + 4) % 7;
secs = time - days*86400;
gm.tm_hour = secs / 3600;
secs -= (gm.tm_hour * 3600L);
gm.tm_min = secs / 60;
gm.tm_sec = secs - (gm.tm_min * 60);
gm.tm_isdst = daylight;
return &gm;
} /* _timecvt */
void ftime(timeptr)
struct timeb *timeptr;
{
long _timesec();
void tzset();
extern long timezone;
extern int daylight;
union REGS timecall, datecall;
union REGS time, date1, date2;
tzset();
timecall.h.ah = 0x2c;
datecall.h.ah = 0x2a;
intdos(&datecall,&date1);
intdos(&timecall,&time);
intdos(&datecall,&date2);
if (date2.x.dx != date1.x.dx) { /* date change at midnight */
if (time.h.ch != 23) { /* date already changed when time read */
date1.x.cx = date2.x.cx;
date1.x.dx = date2.x.dx;
}
}
timeptr->time = _timesec(date1.x.cx, date1.h.dh, date1.h.dl,
time.h.ch, time.h.cl, time.h.dh);
timeptr->millitm = time.h.dl*10;
timeptr->timezone = timezone/60;
timeptr->dstflag = daylight;
} /* ftime */
unsigned sleep(seconds)
unsigned seconds;
{ /* suspend execution */
long time();
long start, now;
start = time(NULL);
do {
now = time(NULL);
} while ((now-start) < seconds);
}
long time(timeptr)
long *timeptr;
{
long _timesec();
long curtime;
union REGS timecall, datecall;
union REGS time, date1, date2;
timecall.h.ah = 0x2c;
datecall.h.ah = 0x2a;
intdos(&datecall,&date1);
intdos(&timecall,&time);
intdos(&datecall,&date2);
if (date2.x.dx != date1.x.dx) { /* date change at midnight */
if (time.h.ch != 23) { /* date already changed when time read */
date1.x.cx = date2.x.cx;
date1.x.dx = date2.x.dx;
}
}
curtime = _timesec(date1.x.cx, date1.h.dh, date1.h.dl,
time.h.ch, time.h.cl, time.h.dh);
if (timeptr != NULL) *timeptr = curtime;
return curtime;
} /* time */
long dostounix(dateptr, timeptr)
struct date *dateptr;
struct time *timeptr;
{
long _timesec();
return _timesec(dateptr->da_year,dateptr->da_mon,dateptr->da_day,
timeptr->ti_hour, timeptr->ti_min, timeptr->ti_sec);
}
clock_t clock(void)
{
extern struct {
unsigned int year;
unsigned char day;
unsigned char month;
unsigned char hour;
unsigned char minute;
unsigned char hour;
unsigned char hundredth;
unsigned char second;
} $$CLOCK; /* time when process started */
long time;
union REGS t, d;
t.h.ah = 0x2c;
d.h.ah = 0x2a;
intdos(&d,&d);
intdos(&t,&t);
time = _timesec(d.x.cx,d.h.dh,d.h.dl,t.h.cl,t.h.ch,t.h.dh);
time = time - _timesec($$CLOCK.year,$$CLOCK.month,$$CLOCK.day,
$$CLOCK.hour,$$CLOCK.minute,$$CLOCK.second);
return time*100+t.h.dl-$$CLOCK.hundredth;
}
long _timesec(year, month, day, hour, min, sec)
int year, month, day, hour, min, sec;
{ /* convert time to seconds since Jan 1 1970 */
extern long timezone;
extern int daylight;
static int daypermonth[13] = {0, 0, 31, 28+31,
31+59, 30+31+59, 31+30+31+59,
30+151, 31+30+151, 31+31+30+151,
30+243, 31+30+243, 30+31+30+243};
int years, leaps;
long days, secs;
years = year - 1970;
leaps = (years + 1) / 4;
if (((years % 4) == 2) && (month > 2)) ++leaps;
days = (long)years*365 + (long)leaps + (long)daypermonth[month]
+ (long)(day-1);
secs = days*86400 + (long)hour*3600 + (long)min*60 + (long)sec + timezone;
if (daylight) return (secs-3600);
return secs;
} /* _timesec */
void tzset()
{
extern int daylight;
extern long timezone;
extern char *tzname[2];
char *tz;
int onehour = 3600;
tz = getenv("TZ=");
if (tz != NULL) {
strncpy(tzname[0],tz,3);
if (strlen(tz) > 3) {
tz += 3;
if (*tz == '-') {
onehour = -onehour;
++tz;
}
timezone = 0;
while (isdigit(*tz)) {
timezone = timezone*10 + (long)onehour*(long)(*tz - '0');
++tz;
}
if (*tz) daylight = 1; else daylight = 0;
strncpy(tzname[1],tz,3);
}
else {
timezone = 0;
daylight = 0;
*tzname[1] = '\0';
}
}
} /* tzset */
double difftime(time2,time1)
time_t time1, time2;
{
return time2-time1;
}
int daylight = 1;
long timezone = 28800;
char *tzname[2] = {"PST", "PDT"};
void getdate(dateblk)
struct date *dateblk;
{
union REGS r;
r.h.ah = 0x2a;
intdos(&r,&r);
dateblk->da_year = r.x.cx;
dateblk->da_mon = r.h.dh;
dateblk->da_day = r.h.dl;
}
void gettime(timep)
struct time *timep;
{
union REGS r;
r.h.ah = 0x2c;
intdos(&r,&r);
timep->ti_min = r.h.cl;
timep->ti_hour = r.h.ch;
timep->ti_hund = r.h.dl;
timep->ti_sec = r.h.dh;
}
void setdate(dateblk)
struct date *dateblk;
{
union REGS r;
r.x.cx = dateblk->da_year;
r.h.dh = dateblk->da_mon;
r.h.dl = dateblk->da_day;
r.h.ah = 0x2b;
intdos(&r,&r);
}
void settime(timep)
struct time *timep;
{
union REGS r;
r.h.cl = timep->ti_min;
r.h.ch = timep->ti_hour;
r.h.dl = timep->ti_hund;
r.h.dh = timep->ti_sec;
r.h.ah = 0x2d;
intdos(&r,&r);
}