use crate::discarded_store::Identity;
pub const YOUNG_FLOOR_MILLISECONDS: i64 = 24 * 60 * 60 * 1000;
pub const DAY_MILLISECONDS: i64 = 24 * 60 * 60 * 1000;
pub const STAMP_RESOLUTION_MILLISECONDS: i64 = 1000;
fn days_from_civil(year: i64, month: i64, day: i64) -> i64 {
let shifted_year: i64 = if month <= 2 { year - 1 } else { year };
let era: i64 = shifted_year.div_euclid(400);
let year_of_era: i64 = shifted_year.rem_euclid(400);
let shifted_month: i64 = if month > 2 { month - 3 } else { month + 9 };
let day_of_year: i64 = (153 * shifted_month + 2) / 5 + day - 1;
let day_of_era: i64 = year_of_era * 365 + year_of_era / 4 - year_of_era / 100 + day_of_year;
return era * 146_097 + day_of_era - 719_468;
}
fn days_in_month(year: i64, month: i64) -> i64 {
return match month {
1 | 3 | 5 | 7 | 8 | 10 | 12 => 31,
4 | 6 | 9 | 11 => 30,
_ if year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) => 29,
_ => 28,
};
}
fn number_at(name: &str, from: usize, to: usize) -> i64 {
return name[from..to].parse::<i64>().unwrap_or(0);
}
pub fn parse_stamp(name: &str) -> Option<i64> {
let bytes: &[u8] = name.as_bytes();
if bytes.len() < 19 || !name.is_ascii() {
return None;
}
let shape: &[u8; 19] = b"dddd-dd-ddTdd-dd-dd";
for (found, wanted) in bytes[..19].iter().zip(shape) {
let fits: bool = if *wanted == b'd' { found.is_ascii_digit() } else { found == wanted };
if !fits {
return None;
}
}
let suffix: &str = &name[19..];
if !(suffix.is_empty() || (suffix.starts_with('-') && suffix.len() > 1 && suffix.as_bytes()[1..].iter().all(u8::is_ascii_digit))) {
return None;
}
let (year, month, day): (i64, i64, i64) = (number_at(name, 0, 4), number_at(name, 5, 7), number_at(name, 8, 10));
let (hour, minute, second): (i64, i64, i64) = (number_at(name, 11, 13), number_at(name, 14, 16), number_at(name, 17, 19));
if !(1..=12).contains(&month) || day < 1 || day > days_in_month(year, month) || hour > 23 || minute > 59 || second > 59 {
return None;
}
return Some(((days_from_civil(year, month, day) * 24 + hour) * 60 + minute) * 60_000 + second * 1000);
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Stamped {
pub name: String,
pub millis: i64,
pub bytes: u128,
pub identity: Identity,
}