use std::ffi::c_int; use std::fmt::{Display, Formatter}; use std::time::{SystemTime, UNIX_EPOCH}; // Convert seconds since epoch to YYYY-MM-DD HH:MM:SS (UTC) // Define the Tm struct from the C standard library #[repr(C)] #[derive(Debug, Copy, Clone)] struct Tm { tm_sec: c_int, // Seconds (0-60) tm_min: c_int, // Minutes (0-59) tm_hour: c_int, // Hours (0-23) tm_mday: c_int, // Day of the month (1-31) tm_mon: c_int, // Month (0-11) tm_year: c_int, // Year since 1900 tm_wday: c_int, // Day of the week (0-6, Sunday = 0) tm_yday: c_int, // Day of the year (0-365) tm_isdst: c_int, // Daylight saving time flag } unsafe extern "C" { fn localtime_r(timep: *const i64, result: *mut Tm) -> *mut Tm; } #[derive(Debug)] pub struct Time { year: i32, month: i32, day: i32, hour: i32, minute: i32, second: i32, } impl Time { pub fn now() -> Result { let now = SystemTime::now(); Time::try_from(now) } /// seconds: seconds since epoch pub fn new(seconds: i64) -> Result { let mut tm: Tm = unsafe { std::mem::zeroed() }; // Call localtime_r with a pointer to our Tm struct let result = unsafe { localtime_r(&seconds, &mut tm) }; // Check if the conversion was successful if result.is_null() { return Err(TimeError::InvalidTime); } Ok(tm.into()) } /// Getter for year pub fn year(&self) -> i32 { self.year } /// Getter for month pub fn month(&self) -> i32 { self.month } /// Getter for day pub fn day(&self) -> i32 { self.day } /// Getter for hour pub fn hour(&self) -> i32 { self.hour } /// Getter for minute pub fn minute(&self) -> i32 { self.minute } /// Getter for second pub fn second(&self) -> i32 { self.second } pub fn format_time(&self) -> String { format!( "{:04}-{:02}-{:02} {:02}:{:02}:{:02}", self.year, self.month, self.day, self.hour, self.minute, self.second ) } } impl Display for Time { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.format_time()) } } impl TryFrom for Time { type Error = TimeError; // Define an appropriate error type fn try_from(time: SystemTime) -> Result { let seconds = time.duration_since(UNIX_EPOCH)?.as_secs() as i64; Time::new(seconds) } } impl From for Time { fn from(tm: Tm) -> Self { Self { year: tm.tm_year + 1900, month: tm.tm_mon + 1, day: tm.tm_mday, hour: tm.tm_hour, minute: tm.tm_min, second: tm.tm_sec, } } } #[derive(Debug)] pub enum TimeError { SystemTimeError(std::time::SystemTimeError), InvalidTime, } impl From for TimeError { fn from(err: std::time::SystemTimeError) -> Self { TimeError::SystemTimeError(err) } }