mirror of
https://github.com/firewalkwithm3/Sensor-Watch.git
synced 2024-11-22 19:20:30 +08:00
Fixed incorrect conversion from UNIX timestamp to watch_date_time.
This commit is contained in:
parent
15eeca6b59
commit
0f9bb0bd37
|
@ -102,13 +102,81 @@ uint16_t watch_utility_days_since_new_year(uint16_t year, uint8_t month, uint8_t
|
||||||
return (is_leap(year) && (month > 2) ? 1 : 0) + DAYS_SO_FAR[month - 1] + day;
|
return (is_leap(year) && (month > 2) ? 1 : 0) + DAYS_SO_FAR[month - 1] + day;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t watch_utility_convert_to_unix_time(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint32_t utc_offset) {
|
// Function taken from `src/time/__year_to_secs.c` of musl libc
|
||||||
uint32_t year_adj = year + 4800;
|
// https://musl.libc.org
|
||||||
uint32_t leap_days = 1 + (year_adj / 4) - (year_adj / 100) + (year_adj / 400);
|
static uint32_t __year_to_secs(uint32_t year, int *is_leap)
|
||||||
uint32_t days = 365 * year_adj + leap_days + watch_utility_days_since_new_year(year, month, day) - 1;
|
{
|
||||||
days -= 2472692; /* Adjust to Unix epoch. */
|
if (year-2ULL <= 136) {
|
||||||
|
int y = year;
|
||||||
|
int leaps = (y-68)>>2;
|
||||||
|
if (!((y-68)&3)) {
|
||||||
|
leaps--;
|
||||||
|
if (is_leap) *is_leap = 1;
|
||||||
|
} else if (is_leap) *is_leap = 0;
|
||||||
|
return 31536000*(y-70) + 86400*leaps;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t timestamp = days * 86400;
|
int cycles, centuries, leaps, rem;
|
||||||
|
|
||||||
|
if (!is_leap) is_leap = &(int){0};
|
||||||
|
cycles = (year-100) / 400;
|
||||||
|
rem = (year-100) % 400;
|
||||||
|
if (rem < 0) {
|
||||||
|
cycles--;
|
||||||
|
rem += 400;
|
||||||
|
}
|
||||||
|
if (!rem) {
|
||||||
|
*is_leap = 1;
|
||||||
|
centuries = 0;
|
||||||
|
leaps = 0;
|
||||||
|
} else {
|
||||||
|
if (rem >= 200) {
|
||||||
|
if (rem >= 300) centuries = 3, rem -= 300;
|
||||||
|
else centuries = 2, rem -= 200;
|
||||||
|
} else {
|
||||||
|
if (rem >= 100) centuries = 1, rem -= 100;
|
||||||
|
else centuries = 0;
|
||||||
|
}
|
||||||
|
if (!rem) {
|
||||||
|
*is_leap = 0;
|
||||||
|
leaps = 0;
|
||||||
|
} else {
|
||||||
|
leaps = rem / 4U;
|
||||||
|
rem %= 4U;
|
||||||
|
*is_leap = !rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
leaps += 97*cycles + 24*centuries - *is_leap;
|
||||||
|
|
||||||
|
return (year-100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function taken from `src/time/__month_to_secs.c` of musl libc
|
||||||
|
// https://musl.libc.org
|
||||||
|
static int __month_to_secs(int month, int is_leap)
|
||||||
|
{
|
||||||
|
static const int secs_through_month[] = {
|
||||||
|
0, 31*86400, 59*86400, 90*86400,
|
||||||
|
120*86400, 151*86400, 181*86400, 212*86400,
|
||||||
|
243*86400, 273*86400, 304*86400, 334*86400 };
|
||||||
|
int t = secs_through_month[month];
|
||||||
|
if (is_leap && month >= 2) t+=86400;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function adapted from `src/time/__tm_to_secs.c` of musl libc
|
||||||
|
// https://musl.libc.org
|
||||||
|
uint32_t watch_utility_convert_to_unix_time(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint32_t utc_offset) {
|
||||||
|
int is_leap;
|
||||||
|
|
||||||
|
// POSIX tm struct starts year at 1900 and month at 0
|
||||||
|
// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/time.h.html
|
||||||
|
uint32_t timestamp = __year_to_secs(year - 1900, &is_leap);
|
||||||
|
timestamp += __month_to_secs(month - 1, is_leap);
|
||||||
|
|
||||||
|
// Regular conversion from musl libc
|
||||||
|
timestamp += (day - 1) * 86400;
|
||||||
timestamp += hour * 3600;
|
timestamp += hour * 3600;
|
||||||
timestamp += minute * 60;
|
timestamp += minute * 60;
|
||||||
timestamp += second;
|
timestamp += second;
|
||||||
|
|
Loading…
Reference in a new issue