diff options
| author | Jesper Jensen <jesper@jnsn.dev> | 2026-02-09 23:26:47 +0100 |
|---|---|---|
| committer | Jesper Jensen <jesper@jnsn.dev> | 2026-02-09 23:27:30 +0100 |
| commit | ff7ea116e097a281b112d44e90f9d1d1abd32b9b (patch) | |
| tree | 85ba3e34e219269a3b0ccae6001feb57be70f08f /src/time.rs | |
| parent | 3856d94661bd5605a839983805ec8ad962c4d307 (diff) | |
Woops, forgot the actual file
Diffstat (limited to 'src/time.rs')
| -rw-r--r-- | src/time.rs | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/time.rs b/src/time.rs new file mode 100644 index 0000000..534cb34 --- /dev/null +++ b/src/time.rs @@ -0,0 +1,87 @@ +use std::time::{Duration, SystemTime, UNIX_EPOCH}; + +#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] +pub struct Timestamp(pub SystemTime); + +impl Timestamp { + pub const ZERO: Timestamp = Timestamp(UNIX_EPOCH); + + pub fn now() -> Timestamp { + return Timestamp(SystemTime::now()); + } + + pub fn duration_since(self, earlier: Timestamp) -> Result<Duration, std::time::SystemTimeError> { + return self.0.duration_since(earlier.0); + } +} + +impl std::ops::Add<Duration> for Timestamp { + type Output = Timestamp; + fn add(self, rhs: Duration) -> Timestamp { + return Timestamp(self.0 + rhs); + } +} + +impl std::ops::Sub<Duration> for Timestamp { + type Output = Timestamp; + fn sub(self, rhs: Duration) -> Timestamp { + return Timestamp(self.0 - rhs); + } +} + +fn is_leap_year(y: u64) -> bool { + return (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0); +} + +fn days_in_month(y: u64, m: u64) -> u64 { + match m { + 1 | 3 | 5 | 7 | 8 | 10 | 12 => 31, + 4 | 6 | 9 | 11 => 30, + 2 => if is_leap_year(y) { 29 } else { 28 }, + _ => panic!("invalid month"), + } +} + +pub fn secs_to_ymd_hms(mut secs: u64) -> (u64, u64, u64, u64, u64, u64) { + let s = secs % 60; + secs /= 60; + let min = secs % 60; + secs /= 60; + let h = secs % 24; + let mut days = secs / 24; + + let mut y = 1970u64; + loop { + let days_in_year = if is_leap_year(y) { 366 } else { 365 }; + if days < days_in_year { + break; + } + days -= days_in_year; + y += 1; + } + + let mut mo = 1u64; + loop { + let dim = days_in_month(y, mo); + if days < dim { + break; + } + days -= dim; + mo += 1; + } + + let day = days + 1; + return (y, mo, day, h, min, s); +} + +pub fn ymd_hms_to_secs(y: u64, m: u64, d: u64, h: u64, min: u64, s: u64) -> u64 { + let mut days = 0u64; + for year in 1970..y { + days += if is_leap_year(year) { 366 } else { 365 }; + } + for month in 1..m { + days += days_in_month(y, month); + } + days += d - 1; + return days * 86400 + h * 3600 + min * 60 + s; +} |
