tank_core/
interval.rs

1use std::time::Duration;
2
3const SECS_IN_DAY: i64 = 60 * 60 * 24;
4
5#[derive(Default, Debug, Clone, Copy, PartialEq)]
6pub struct Interval {
7    months: i64,
8    days: i64,
9    nanos: i128,
10}
11
12impl Interval {
13    pub fn new(months: i64, days: i64, nanos: i128) -> Self {
14        Self {
15            months,
16            days,
17            nanos,
18        }
19    }
20
21    pub const fn from_duration(duration: &Duration) -> Self {
22        Self {
23            months: 0,
24            days: 0,
25            nanos: duration.as_nanos() as _,
26        }
27    }
28
29    pub const fn from_nanos(micros: i128) -> Self {
30        const NANOS_IN_DAY: i128 = (SECS_IN_DAY * 1_000_000_000) as _;
31        Self {
32            months: 0,
33            days: (micros / NANOS_IN_DAY) as _,
34            nanos: (micros % NANOS_IN_DAY),
35        }
36    }
37
38    pub const fn from_micros(micros: i128) -> Self {
39        const MICROS_IN_DAY: i128 = (SECS_IN_DAY * 1_000_000) as _;
40        Self {
41            months: 0,
42            days: (micros / MICROS_IN_DAY) as _,
43            nanos: (micros % MICROS_IN_DAY) * 1_000_000,
44        }
45    }
46
47    pub const fn from_millis(millis: i128) -> Self {
48        const MILLIS_IN_DAY: i128 = (SECS_IN_DAY * 1_000) as _;
49        Self {
50            months: 0,
51            days: (millis / MILLIS_IN_DAY) as _,
52            nanos: ((millis % MILLIS_IN_DAY) * 1_000),
53        }
54    }
55
56    pub const fn from_secs(secs: i64) -> Self {
57        Self {
58            months: 0,
59            days: (secs / SECS_IN_DAY) as _,
60            nanos: ((secs % SECS_IN_DAY) * 1_000_000_000) as _,
61        }
62    }
63
64    pub const fn from_mins(mins: i64) -> Self {
65        const MINS_IN_DAYS: i64 = 60 * 24;
66        Self {
67            months: 0,
68            days: (mins / MINS_IN_DAYS),
69            nanos: ((mins % MINS_IN_DAYS) * 60 * 1_000_000_000) as _,
70        }
71    }
72
73    pub const fn from_days(days: i64) -> Self {
74        Self {
75            months: 0,
76            days: days,
77            nanos: 0,
78        }
79    }
80
81    pub const fn from_weeks(weeks: i64) -> Self {
82        Self {
83            months: 0,
84            days: weeks * 7,
85            nanos: 0,
86        }
87    }
88
89    pub const fn is_zero(&self) -> bool {
90        self.months == 0 && self.days == 0 && self.nanos == 0
91    }
92
93    pub const fn as_duration(&self, days_in_month: f64) -> Duration {
94        const NANOS_IN_SEC: i128 = 1_000_000_000;
95        const NANOS_IN_DAY: i128 = SECS_IN_DAY as i128 * NANOS_IN_SEC;
96        let nanos = (self.months as f64) * days_in_month * (NANOS_IN_DAY as f64); // months
97        let nanos = nanos as i128 + self.days as i128 * NANOS_IN_DAY; // days
98        let nanos = nanos + self.nanos as i128 * 1000; // micros
99        let secs = (nanos / NANOS_IN_SEC) as u64;
100        let nanos = (nanos % NANOS_IN_SEC) as u32;
101        Duration::new(secs, nanos)
102    }
103}