#include #include "timeutil.h" /* TODO: mktime: DST not supported */ time_t mktime(struct tm *time) { /* Normalize time */ time->tm_min += (time->tm_sec / 60); time->tm_hour += (time->tm_min / 60); time->tm_mday += (time->tm_hour / 24); time->tm_sec %= 60; time->tm_min %= 60; time->tm_hour %= 24; /* Normalize date */ int days = daysin(time->tm_mon, time->tm_year + 1900); while(time->tm_mday > days) { time->tm_mday -= days; if(++time->tm_mon == 12) { time->tm_mon = 0; time->tm_year++; } days = daysin(time->tm_mon, time->tm_year + 1900); } /* Determine day in year */ time->tm_yday = time->tm_mday - 1; for(int i = 0; i < time->tm_mon; i++) time->tm_yday += daysin(i, time->tm_year + 1900); /* Determine day in week. The calendar has a period of 400 years and 1601-01-01 was a Monday. */ /* Years elapsed since last 400n+1 year (1601-2001-etc). */ int yr = (time->tm_year + 1900 - 1) % 400; /* Leap years during this period */ int leaps = (yr / 4) - (yr >= 100) - (yr >= 200) - (yr >= 300); /* Days elapsed since 01-01 on the last 400n+1 year */ days = 365 * yr + leaps + time->tm_yday; /* Current day of week (1 is Monday on 01-01 of last 400n+1 year) */ time->tm_wday = (1 + days) % 7; /* We don't determine DST at the targeted time */ time->tm_isdst = 0; /* Number of periods elapsed since 1601-01-01 (may be negative) */ int periods = (time->tm_year + 1900 - 1601) / 400; periods -= (time->tm_year + 1900 < 1601); /* Days elapsed since 1970-01-01; the calendar period is 146097 days and there are 134774 days between 1601-01-01 and 1970-01-01 */ days += 146097 * periods - 134774; time_t t = days; t = 24 * t + time->tm_hour; t = 60 * t + time->tm_min; t = 60 * t + time->tm_sec; return t; }