Create the module to convert datetime to unix epoch

main
kirbylife 2023-03-30 22:09:35 -06:00
parent 12232bfba9
commit e34838c985
1 changed files with 122 additions and 0 deletions

122
src/datetime.rs 100644
View File

@ -0,0 +1,122 @@
// 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 mut year: i64 = self.year as i64 - 1900;
let mut month: i64 = self.month as i64 - 1;
if month >= 12 || month < 0 {
let mut adj = month / 12;
month %= 12;
if month < 0 {
adj -= 1;
month += 12;
}
year += adj as i64;
}
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
}
}
fn year_to_secs(year: i64) -> (i64, bool) {
let is_leap: bool;
let res: i64;
if year - 2 <= 136 {
let y = year as i32;
let mut leaps = (y - 68) >> 2;
if !((y - 68) & 3 != 0) {
leaps -= 1;
is_leap = true;
} else {
is_leap = false;
}
res = 31536000 * (y - 70) as i64 + 86400 * leaps as i64;
} else {
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
}