ack/lang/cem/libcc.ansi/time/mktime.c
1989-06-12 15:22:14 +00:00

132 lines
2.8 KiB
C

/*
* mktime - convert local time into calendar time
*/
/* $Header$ */
#include <time.h>
#include <limits.h>
#include "loc_incl.h"
time_t
mktime(register struct tm *timep)
{
int day, year, month, yday;
long tmp_sec, tz = _tzone();
register time_t seconds, localseconds;
int overflow = 0;
unsigned dst;
timep->tm_min += timep->tm_sec / 60;
timep->tm_sec %= 60;
if (timep->tm_sec < 0) {
timep->tm_sec += 60;
timep->tm_min--;
}
timep->tm_hour += timep->tm_min / 60;
timep->tm_min = timep->tm_min % 60;
if (timep->tm_min < 0) {
timep->tm_min += 60;
timep->tm_hour--;
}
day = timep->tm_hour / 24;
timep->tm_hour= timep->tm_hour % 24;
if (timep->tm_hour < 0) {
timep->tm_hour += 24;
day--;
}
timep->tm_year += timep->tm_mon / 12;
timep->tm_mon %= 12;
if (timep->tm_mon < 0) {
timep->tm_mon += 12;
timep->tm_year--;
}
day += (timep->tm_mday - 1);
while (day < 0) {
day += YEARSIZE(YEAR1 + timep->tm_year - 1);
timep->tm_year--;
}
while (day >= YEARSIZE(YEAR1 + timep->tm_year)) {
day -= YEARSIZE(YEAR1 + timep->tm_year);
timep->tm_year++;
}
while (day >= _ytab[LEAPYEAR(YEAR1 + timep->tm_year)][timep->tm_mon]) {
day -= _ytab[LEAPYEAR(YEAR1 + timep->tm_year)][timep->tm_mon];
if (++(timep->tm_mon) == 12) {
timep->tm_mon = 0;
timep->tm_year++;
}
}
timep->tm_mday = day + 1;
year = 70;
if (timep->tm_year < year) return -1;
seconds = 0;
while (!overflow && year < timep->tm_year) {
tmp_sec = SECS_DAY * YEARSIZE(YEAR1 + year);
if (TIME_MAX - tmp_sec <= seconds) overflow++;
else {
seconds += tmp_sec;
year++;
}
}
yday = month = 0;
while (!overflow && month < timep->tm_mon) {
yday += _ytab[LEAPYEAR(YEAR1 + year)][month];
month++;
}
yday += (timep->tm_mday - 1);
if (!overflow) {
tmp_sec = yday * SECS_DAY;
if (TIME_MAX - tmp_sec <= seconds) overflow++;
else seconds += tmp_sec;
}
timep->tm_yday = yday; /* ??? assignments should be later */
/* day 0 was thursday (4) */
timep->tm_wday = (seconds / SECS_DAY + 4) % 7;
if (timep->tm_isdst < 0)
dst = _dstget(timep);
else if (timep->tm_isdst)
dst = 60 * 60;
else dst = 0;
if (!overflow) {
tmp_sec = timep->tm_hour * 60 * 60;
if (TIME_MAX - tmp_sec <= seconds) overflow++;
else seconds += tmp_sec;
}
if (!overflow) {
tmp_sec = timep->tm_min * 60;
if (TIME_MAX - tmp_sec <= seconds) overflow++;
else seconds += tmp_sec;
}
if (!overflow) {
tmp_sec = timep->tm_sec;
if (TIME_MAX - tmp_sec <= seconds) overflow++;
else seconds += tmp_sec;
}
localseconds = seconds;
if (!overflow) {
tmp_sec = tz;
if (((tmp_sec > 0) && (TIME_MAX - tmp_sec <= seconds))
|| ((tmp_sec < 0) && (seconds < -tmp_sec)))
overflow++;
else seconds += tmp_sec;
}
if (!overflow) {
tmp_sec = dst;
if (tmp_sec > seconds) overflow++;
else seconds -= tmp_sec;
}
if (overflow) return (time_t)-1;
return seconds;
}