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); let nanos = nanos as i128 + self.days as i128 * NANOS_IN_DAY; let nanos = nanos + self.nanos as i128 * 1000; let secs = (nanos / NANOS_IN_SEC) as u64;
100 let nanos = (nanos % NANOS_IN_SEC) as u32;
101 Duration::new(secs, nanos)
102 }
103}