1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
use chrono::{DateTime, Duration, TimeZone, Utc}; const NS_PER_US: u32 = 1_000; const NS_PER_MS: u32 = 1_000_000; #[inline] fn us_to_ns(us: u32) -> u32 { us * NS_PER_US } #[inline] fn ms_to_ns(ms: u32) -> u32 { ms * NS_PER_MS } #[derive(Debug, Default)] pub struct Parts { pub year: i32, pub month: u32, pub day: u32, pub hour: u32, pub minute: u32, pub second: u32, pub millisecond: u32, pub microsecond: u32, pub nanosecond: u32, } #[derive(Debug)] pub struct Epoch { pub datetime: DateTime<Utc>, } impl From<Parts> for Epoch { fn from(parts: Parts) -> Self { let total_ns = parts.nanosecond + us_to_ns(parts.microsecond) + ms_to_ns(parts.millisecond); let datetime = Utc.ymd(parts.year, parts.month, parts.day).and_hms_nano( parts.hour, parts.minute, parts.second, total_ns, ); Epoch::new(datetime) } } impl Epoch { pub fn new(datetime: DateTime<Utc>) -> Epoch { Epoch { datetime } } pub fn from_parts(parts: Parts) -> Epoch { parts.into() } pub fn from_epoch_s(epoch_s: i64) -> Epoch { let datetime = Utc.timestamp(epoch_s, 0); Epoch::new(datetime) } pub fn from_epoch_ms(epoch_ms: i64) -> Epoch { let datetime = Utc.timestamp_millis(epoch_ms); Epoch::new(datetime) } pub fn from_epoch_us(epoch_us: i64) -> Epoch { let epoch_ns = epoch_us * 1000; Epoch::from_epoch_ns(epoch_ns) } pub fn from_epoch_ns(epoch_ns: i64) -> Epoch { let datetime = Utc.timestamp_nanos(epoch_ns); Epoch::new(datetime) } pub fn epoch_s(&self) -> i64 { self.datetime.timestamp() } pub fn epoch_ms(&self) -> i64 { self.datetime.timestamp_millis() } pub fn epoch_us(&self) -> i64 { ((self.epoch_ns() as f64) / 1000.0).round() as i64 } pub fn epoch_ns(&self) -> i64 { self.datetime.timestamp_nanos() } pub fn plus_duration(mut self, duration: Duration) -> Self { self.datetime = self.datetime + duration; self } pub fn minus_duration(mut self, duration: Duration) -> Self { self.datetime = self.datetime - duration; self } } impl Default for Epoch { fn default() -> Self { Self { datetime: Utc::now(), } } }