#include "project.h" static int is_leap (unsigned year) { if (year % 4) return 0; if (year % 100) return 1; if (year % 400) return 0; return 1; } UTC time_epoch_to_utc (EPOCH epoch) { UTC u; uint64_t day; unsigned y400, y100, y4; day = epoch.s / 86400; epoch.s -= day * 86400; day += 134774; u.wday = day % 7; u.wday++; y400 = day / 146097; /*146097 days in 400 years */ day -= (y400 * 146097); y100 = day / 36524; /*36524 days in 100 years */ day -= (y100 * 36524); y4 = day / 1461; /*1461 days in 4 years */ day -= (y4 * 1461); /* This may look redundant but 31 Dec in year 4 is special case */ if (day < 1095) { /*1095 days in 3 years */ u.year = day / 365; /*365 days in a year */ day -= (365 * u.year); } else { u.year = 3; day -= 1095; } /* Now put it all back together */ u.year += 1601; u.year += 4 * y4; u.year += 100 * y100; u.year += 400 * y400; u.jday = day + 1; u.is_leap = is_leap (u.year); if (!u.is_leap) { /*Days and months for ordinary years */ if (u.jday < 32) { u.month = 1; u.mday = u.jday; } else if (u.jday < 60) { u.month = 2; u.mday = u.jday - 31; } else if (u.jday < 91) { u.month = 3; u.mday = u.jday - 59; } else if (u.jday < 121) { u.month = 4; u.mday = u.jday - 90; } else if (u.jday < 152) { u.month = 5; u.mday = u.jday - 120; } else if (u.jday < 182) { u.month = 6; u.mday = u.jday - 151; } else if (u.jday < 213) { u.month = 7; u.mday = u.jday - 181; } else if (u.jday < 244) { u.month = 8; u.mday = u.jday - 212; } else if (u.jday < 274) { u.month = 9; u.mday = u.jday - 243; } else if (u.jday < 305) { u.month = 10; u.mday = u.jday - 273; } else if (u.jday < 335) { u.month = 11; u.mday = u.jday - 304; } else { u.month = 12; u.mday = u.jday - 334; } } else { /*And leap years */ if (u.jday < 32) { u.month = 1; u.mday = u.jday; } else if (u.jday < 61) { u.month = 2; u.mday = u.jday - 31; } else if (u.jday < 92) { u.month = 3; u.mday = u.jday - 60; } else if (u.jday < 122) { u.month = 4; u.mday = u.jday - 91; } else if (u.jday < 153) { u.month = 5; u.mday = u.jday - 121; } else if (u.jday < 183) { u.month = 6; u.mday = u.jday - 152; } else if (u.jday < 214) { u.month = 7; u.mday = u.jday - 182; } else if (u.jday < 245) { u.month = 8; u.mday = u.jday - 213; } else if (u.jday < 275) { u.month = 9; u.mday = u.jday - 244; } else if (u.jday < 306) { u.month = 10; u.mday = u.jday - 274; } else if (u.jday < 336) { u.month = 11; u.mday = u.jday - 305; } else { u.month = 12; u.mday = u.jday - 335; } } u.hour = epoch.s / 3600; epoch.s -= u.hour * 3600; u.minute = epoch.s / 60; epoch.s -= u.minute * 60; u.second = epoch.s; u.nanosecond = epoch.ns; return u; } EPOCH time_utc_to_epoch (UTC u) { unsigned y400; unsigned y100; unsigned y4; EPOCH ret; static int const mdays[] = { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; static int const lmdays[] = { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }; u.is_leap = is_leap (u.year); if (u.year < 100) u.year += 2000; if (!u.jday) { if (u.is_leap) u.jday = u.mday + lmdays[u.month]; else u.jday = u.mday + mdays[u.month]; } u.year -= 1601; y400 = u.year / 400; u.year -= y400 * 400; y100 = u.year / 100; u.year -= y100 * 100; y4 = u.year / 4; u.year -= y4 * 4; ret.s = u.jday - 1; ret.s += u.year * 365; ret.s += y4 * 1461; ret.s += y100 * 36524; ret.s += y400 * 146097; ret.s -= 134774; ret.s *= 86400; ret.s += u.second; ret.s += u.minute * 60; ret.s += u.hour * 3600; ret.ns = u.nanosecond; return ret; } void utc_to_str (char *dst, UTC u) { const char *dname[] = {"Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat", "Sun"}; const char *mname[] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; sprintf (dst, "%s %04d-%s-%02d %02d:%02d:%02d.%09d", dname[u.wday], u.year, mname[u.month], u.mday, u.hour, u.minute, u.second, u.nanosecond); } void time_print_utc (const char *p, UTC u) { const char *dname[] = {"Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat", "Sun"}; const char *mname[] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; printf ("%s%s %04d-%s-%02d %02d:%02d:%02d.%09d\r\n", p ? p : "", dname[u.wday], u.year, mname[u.month], u.mday, u.hour, u.minute, u.second, u.nanosecond); } void time_print_epoch (const char *p, EPOCH e) { UTC u = time_epoch_to_utc (e); time_print_utc (p, u); }