#include #include #include #include #include #include #include #define SECONDS_PER_DAY 86400 static int isleap(int year) { return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); } static int make_yday(int year, int month) { static const short int upto[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; int yd; yd = upto[month - 1]; if (month > 2 && isleap(year)) yd++; return yd; } static int day_of_week(int year, int mon, int day) { static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; year -= mon < 3; return (year + year / 4 - year / 100 + year / 400 + t[mon - 1] + day) % 7; } static time_t broken_down_to_unix(time_t year, time_t yday, time_t hour, time_t min, time_t sec) { return sec + min * 60 + hour * 3600 + yday * 86400 + (year - 70) * 31536000 + ((year - 69) / 4) * 86400 - ((year - 1) / 100) * 86400 + ((year + 299) / 400) * 86400; } static void time_to_struct_tm(time_t time, struct tm* result) { result->tm_isdst = 0; // No DST/timezone support for now. int year = 1970; while (time > 0) { time_t seconds_in_year = (isleap(year) ? 366 : 365) * SECONDS_PER_DAY; if (seconds_in_year <= time) { year++; time -= seconds_in_year; continue; } break; } int month_days[] = {31, isleap(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int month = 0; while (1) { time_t seconds_in_month = month_days[month] * SECONDS_PER_DAY; if (seconds_in_month <= time) { month++; time -= seconds_in_month; continue; } break; } int day = (int)(time / SECONDS_PER_DAY); time %= SECONDS_PER_DAY; assert(day < month_days[month]); int hour = (int)(time / 3600); time %= 3600; int min = (int)(time / 60); time %= 60; result->tm_year = year - 1900; result->tm_mon = month + 1; result->tm_yday = make_yday(year, month + 1) + day; result->tm_wday = day_of_week(year, month + 1, day + 1); result->tm_mday = day + 1; result->tm_hour = hour; result->tm_min = min; result->tm_sec = (int)time; } const char* wday_names[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; const char* month_names[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; extern "C" { clock_t clock() { struct timespec tp; clock_gettime(CLOCK_PROCTIME, &tp); return (tp.tv_sec * CLOCKS_PER_SEC) + (tp.tv_nsec / 1000); } time_t time(time_t* tloc) { struct timespec tp; clock_gettime(CLOCK_REALTIME, &tp); if (tloc) { *tloc = tp.tv_sec; } return tp.tv_sec; } int clock_gettime(clockid_t clock_id, struct timespec* tp) { return (int)__lc_fast_syscall2(SYS_clock_gettime, clock_id, tp); } int gettimeofday(struct timeval* tp, __lc_unused void* tzp) { struct timespec tspec; clock_gettime(CLOCK_REALTIME, &tspec); tp->tv_sec = tspec.tv_sec; tp->tv_usec = tspec.tv_nsec / 1000; return 0; } struct tm* localtime(const time_t* time) { static struct tm result; return localtime_r(time, &result); } struct tm* gmtime(const time_t* time) { static struct tm result; return gmtime_r(time, &result); } struct tm* localtime_r(const time_t* time, struct tm* result) { return gmtime_r(time, result); // FIXME: Implement timezones. } struct tm* gmtime_r(const time_t* time, struct tm* result) { time_to_struct_tm(*time, result); return result; } char* asctime_r(const struct tm* time, char buf[26]) { strftime(buf, 26, "%a %b %d %H:%M:%S %Y\n", time); return buf; } char* asctime(const struct tm* time) { static char buf[26]; return asctime_r(time, buf); } char* ctime_r(const time_t* time, char buf[26]) { struct tm stm; return asctime_r(localtime_r(time, &stm), buf); } char* ctime(const time_t* time) { return asctime(localtime(time)); } time_t mktime(struct tm* time) { return broken_down_to_unix(time->tm_year, time->tm_yday, time->tm_hour, time->tm_min, time->tm_sec); } double difftime(time_t time2, time_t time1) { return (double)(time2 - time1); } }