| 1 | #include <time/date_time.h> |
|---|---|
| 2 | |
| 3 | static uint8_t get_jan_1st_weekday(year_t year) { |
| 4 | year_t y = year - 1; |
| 5 | return (1 + y + (y / 4) - (y / 100) + (y / 400)) % 7; |
| 6 | } |
| 7 | |
| 8 | struct date_time_expanded date_time_expand(const struct date_time *dt) { |
| 9 | struct date_time_expanded out; |
| 10 | out.year = dt->year; |
| 11 | |
| 12 | time_s_t remaining_sec = dt->sec; |
| 13 | out.hour = remaining_sec / 3600; |
| 14 | remaining_sec %= 3600; |
| 15 | out.minute = remaining_sec / 60; |
| 16 | out.second = remaining_sec % 60; |
| 17 | |
| 18 | /* ( Jan 1 day + day of year ) % 7 */ |
| 19 | uint8_t jan_1 = get_jan_1st_weekday(year: dt->year); |
| 20 | out.day_of_week = (jan_1 + dt->day) % 7; |
| 21 | |
| 22 | uint16_t remaining_days = dt->day; /* 0 indexed */ |
| 23 | uint8_t m = 0; |
| 24 | |
| 25 | /* m is a 0-11 month, days_in_month takes 1-12 */ |
| 26 | while (m < 12 && remaining_days >= days_in_month(year: dt->year, month: m + 1)) { |
| 27 | remaining_days -= days_in_month(year: dt->year, month: m + 1); |
| 28 | m++; |
| 29 | } |
| 30 | |
| 31 | out.month = m; |
| 32 | out.day_of_month = remaining_days + 1; /* 1 indexed */ |
| 33 | return out; |
| 34 | } |
| 35 | |
| 36 | void date_time_compact(const struct date_time_expanded *expanded, |
| 37 | struct date_time *out) { |
| 38 | out->year = expanded->year; |
| 39 | |
| 40 | out->sec = |
| 41 | (expanded->hour * 3600) + (expanded->minute * 60) + expanded->second; |
| 42 | |
| 43 | uint16_t day_of_year = 0; |
| 44 | |
| 45 | for (uint8_t m = 0; m < expanded->month; m++) |
| 46 | day_of_year += days_in_month(year: expanded->year, month: m + 1); |
| 47 | |
| 48 | day_of_year += (expanded->day_of_month - 1); |
| 49 | |
| 50 | out->day = day_of_year; |
| 51 | } |
| 52 |