// This code was extracted from http://git.musl-libc.org/cgit/musl/tree/src/time?h=v0.9.15 pub struct Datetime { pub year: u16, pub month: u8, pub day: u8, pub hours: u8, pub minutes: u8, pub seconds: u8, } impl Datetime { pub fn unix_epoch(&self) -> u64 { let year: i64 = self.year as i64 - 1900; let month: i64 = self.month as i64 - 1; let (mut t, is_leap) = year_to_secs(year); t += month_to_secs(month, is_leap); t += 86400 * (self.day as i64 - 1); t += 3600 * self.hours as i64; t += 60 * self.minutes as i64; t += self.seconds as i64; t as u64 } pub fn from_ds3231(rtc: &mut T) -> Self { let year = rtc.year().map_err(|_| ()).unwrap(); let month = rtc.month().map_err(|_| ()).unwrap(); let day = rtc.day().map_err(|_| ()).unwrap(); let hours = match rtc.hours().map_err(|_| ()).unwrap() { ds323x::Hours::AM(val) => val, ds323x::Hours::PM(val) => val + 12, ds323x::Hours::H24(val) => val, }; let minutes = rtc.minutes().map_err(|_| ()).unwrap(); let seconds = rtc.seconds().map_err(|_| ()).unwrap(); Datetime { year, month, day, hours, minutes, seconds, } } } fn year_to_secs(year: i64) -> (i64, bool) { let is_leap: bool; let res: i64; let mut cycles: i64; let centuries: i64; let mut leaps: i64; let mut rem: i64; cycles = (year - 100) / 400; rem = (year - 100) % 400; if rem < 0 { cycles -= 1; rem += 400; } if rem == 0 { is_leap = true; 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 == 0 { is_leap = false; leaps = 0; } else { leaps = rem / 4; rem %= 4; is_leap = rem == 0; } } leaps += 97 * cycles + 24 * centuries - (is_leap as i64); res = (year - 100) * 31536000 + leaps * 86400 + 946684800 + 86400; (res, is_leap) } fn month_to_secs(month: i64, is_leap: bool) -> i64 { const SECS_THROUGH_MONTH: [i64; 12] = [ 0, // Jan 31 * 86400, // Feb 59 * 86400, // Mar 90 * 86400, // Apr 120 * 86400, // May 151 * 86400, // Jun 181 * 86400, // Jul 212 * 86400, // Aug 243 * 86400, // Sep 273 * 86400, // Oct 304 * 86400, // Nov 334 * 86400, // Dec ]; let mut t = SECS_THROUGH_MONTH[month as usize]; if is_leap && month >= 2 { t += 86400; } t }