use std::time::SystemTime;
const DAYS: [&str; 7] = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
const MONTHS: [&str; 12] = [
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
];
const DAYS_IN_MONTHS: [i64; 12] = [31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29];
const MINUTE: i64 = 60;
const HOUR: i64 = MINUTE * 60;
const DAY: i64 = HOUR * 24;
const DAYS_4_YEARS: i64 = 365 * 4 + 1;
const DAYS_100_YEARS: i64 = 365 * 100 + 24;
const DAYS_400_YEARS: i64 = 365 * 400 + 97;
const MARCH_01_2000: i64 = 951868800;
pub struct DateTime {
pub timestamp: i64,
pub year: u16,
pub month: u8,
pub day: u8,
pub weekday: u8,
pub hour: u8,
pub minute: u8,
pub second: u8,
}
impl DateTime {
pub fn now() -> Self {
let timestamp = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs() as i64;
Self::from(timestamp)
}
pub fn get_timestamp(&self) -> i64 {
self.timestamp
}
}
impl From<i64> for DateTime {
fn from(timestamp: i64) -> Self {
let seconds = timestamp - MARCH_01_2000;
let mut days = seconds / DAY;
let mut remaining_seconds = seconds % 86400;
if remaining_seconds < 0 {
remaining_seconds += 86400;
days -= 1;
}
let mut weekday = (days + 3) % 7;
if weekday < 0 {
weekday += 7;
}
let mut y400_cycles = days / DAYS_400_YEARS;
let mut remaining_days = days % DAYS_400_YEARS;
if remaining_days < 0 {
remaining_days += DAYS_400_YEARS;
y400_cycles -= 1;
}
let mut y100_cycles = remaining_days / DAYS_100_YEARS;
if y100_cycles == 4 {
y100_cycles -= 1;
}
remaining_days -= y100_cycles * DAYS_100_YEARS;
let mut y4_cycles = remaining_days / DAYS_4_YEARS;
if y4_cycles == 25 {
y4_cycles -= 1;
}
remaining_days -= y4_cycles * DAYS_4_YEARS;
let mut remaining_years = remaining_days / 365;
if remaining_years == 4 {
remaining_years -= 1;
}
remaining_days -= remaining_years * 365;
let mut year =
(remaining_years + 4 * y4_cycles + 100 * y100_cycles + 400 * y400_cycles) + 2000;
let mut months = 0;
while DAYS_IN_MONTHS[months] <= remaining_days {
remaining_days -= DAYS_IN_MONTHS[months];
months += 1;
}
let mut month = months + 2;
if month >= 12 {
month -= 12;
year += 1;
}
let day = remaining_days + 1;
let hour = remaining_seconds / 3600;
let minute = remaining_seconds / 60 % 60;
let second = remaining_seconds % 60;
Self {
timestamp,
year: year as u16,
month: month as u8,
day: day as u8,
weekday: weekday as u8,
hour: hour as u8,
minute: minute as u8,
second: second as u8,
}
}
}
impl ToString for DateTime {
fn to_string(&self) -> String {
format!(
"{}, {:02} {:02} {} {:02}:{:02}:{:02} GMT",
DAYS[self.weekday as usize],
self.day,
MONTHS[self.month as usize],
self.year,
self.hour,
self.minute,
self.second
)
}
}