summaryrefslogtreecommitdiff
path: root/src/time.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/time.rs')
-rw-r--r--src/time.rs87
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;
+}