Files
photon/libc/time/gmtime.c

76 lines
2.1 KiB
C

#include <time.h>
#include <stdbool.h>
static struct tm g_time_struct = {};
/* to the suprise of nobody, this is from stack overflow.
* https://stackoverflow.com/questions/21593692/convert-unix-timestamp-to-date-without-system-libs
*/
struct tm *gmtime(const time_t *timer)
{
unsigned int seconds, minutes, hours, days, year, month;
unsigned int day_of_week;
seconds = *timer;
/* calculate minutes */
minutes = seconds / 60;
seconds -= minutes * 60;
/* calculate hours */
hours = minutes / 60;
minutes -= hours * 60;
/* calculate days */
days = hours / 24;
hours -= days * 24;
/* Unix time starts in 1970 on a Thursday */
year = 1970;
day_of_week = 4;
while(1) {
bool leap_year = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
uint16_t days_in_year = leap_year ? 366 : 365;
if (days >= days_in_year) {
day_of_week += leap_year ? 2 : 1;
days -= days_in_year;
if (day_of_week >= 7) {
day_of_week -= 7;
}
++year;
} else {
g_time_struct.tm_yday = days;
day_of_week += days;
day_of_week %= 7;
/* calculate the month and day */
static const uint8_t days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
for (month = 0; month < 12; ++month) {
uint8_t dim = days_in_month[month];
/* add a day to feburary if this is a leap year */
if (month == 1 && leap_year) {
++dim;
}
if (days >= dim) {
days -= dim;
} else {
break;
}
}
break;
}
}
g_time_struct.tm_sec = seconds;
g_time_struct.tm_min = minutes;
g_time_struct.tm_hour = hours;
g_time_struct.tm_mday = days + 1;
g_time_struct.tm_mon = month;
g_time_struct.tm_year = year - 1900;
g_time_struct.tm_wday = day_of_week;
return &g_time_struct;
}