1use std::time::{SystemTime, UNIX_EPOCH};
2#[cfg(feature = "async")]
3use std::{future::Future, pin::Pin};
4
5macro_rules! impl_for{
6 ($($t:ty),*) => {
7 $(
8 impl DurationExt for $t {
9 fn millis(&self) -> std::time::Duration {
10 std::time::Duration::from_millis(*self as u64)
11 }
12 fn seconds(&self) -> std::time::Duration {
13 std::time::Duration::from_secs(*self as u64)
14 }
15 }
16 )*
17 };
18}
19
20pub trait DurationExt {
21 fn millis(&self) -> std::time::Duration;
22 fn seconds(&self) -> std::time::Duration;
23 fn minutes(&self) -> std::time::Duration {
24 self.seconds() * 60
25 }
26 fn hours(&self) -> std::time::Duration {
27 self.minutes() * 60
28 }
29 fn days(&self) -> std::time::Duration {
30 self.hours() * 24
31 }
32}
33
34impl_for!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize, f64, f32, u128, i128);
35
36#[cfg(feature = "async")]
37type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
38#[cfg(feature = "time_async")]
39pub trait SleepAsyncExt {
40 fn sleep_async(&self) -> BoxFuture<'_, ()>;
41}
42#[cfg(feature = "time_async")]
43impl SleepAsyncExt for std::time::Duration {
44 fn sleep_async(&self) -> BoxFuture<'_, ()> {
45 Box::pin(tokio::time::sleep(*self))
46 }
47}
48pub trait DurationToUnix {
49 fn to_past_unix_secs(&self) -> u64;
50 fn to_future_unix_secs(&self) -> u64;
51}
52impl DurationToUnix for std::time::Duration {
53 fn to_past_unix_secs(&self) -> u64 {
54 (now() - *self).unix_secs()
55 }
56 fn to_future_unix_secs(&self) -> u64 {
57 (now() + *self).unix_secs()
58 }
59}
60pub trait TimeExt {
61 fn unix_secs(&self) -> u64;
62 fn unix_millis(&self) -> u64;
63 fn unix_nanos(&self) -> u64;
64 fn unix_micros(&self) -> u64;
65 fn unix_days(&self) -> u32 {
66 (self.unix_secs() / (60 * 60 * 24)) as u32
67 }
68}
69impl TimeExt for SystemTime {
70 fn unix_millis(&self) -> u64 {
71 self.duration_since(UNIX_EPOCH)
72 .unwrap_or_default()
73 .as_millis() as u64
74 }
75
76 fn unix_secs(&self) -> u64 {
77 self.duration_since(UNIX_EPOCH)
78 .unwrap_or_default()
79 .as_secs()
80 }
81
82 fn unix_nanos(&self) -> u64 {
83 self.duration_since(UNIX_EPOCH)
84 .unwrap_or_default()
85 .as_nanos() as u64
86 }
87
88 fn unix_micros(&self) -> u64 {
89 self.duration_since(UNIX_EPOCH)
90 .unwrap_or_default()
91 .as_micros() as u64
92 }
93}
94
95pub trait SleepExt {
96 fn sleep_sync(&self);
97}
98impl SleepExt for std::time::Duration {
99 fn sleep_sync(&self) {
100 SystemTime::now().unix_secs();
101 std::thread::sleep(*self)
102 }
103}
104pub trait HMS {
105 fn hms(&self) -> String;
106 fn hmsxxx(&self) -> String;
107}
108
109impl HMS for std::time::Duration {
110 fn hms(&self) -> String {
111 let secs = self.as_secs();
112 let hours = secs / 3600;
113 let minutes = (secs % 3600) / 60;
114 let seconds = secs % 60;
115 format!("{:02}:{:02}:{:02}", hours, minutes, seconds)
116 }
117 fn hmsxxx(&self) -> String {
118 let secs = self.as_secs();
119 let hours = secs / 3600;
120 let minutes = (secs % 3600) / 60;
121 let seconds = secs % 60;
122 let millis = self.subsec_millis();
123 format!("{:02}:{:02}:{:02}.{:03}", hours, minutes, seconds, millis)
124 }
125}
126pub fn now() -> SystemTime {
127 SystemTime::now()
128}
129pub fn instant_now() -> std::time::Instant {
130 std::time::Instant::now()
131}
132pub trait InstantExt {
133 fn print_elapsed(&self);
134 fn reset(&mut self);
135 fn eprint_elapsed(&self);
136 fn print_elapsed_with_msg(&self, msg: &str);
137 fn eprint_elapsed_with_msg(&self, msg: &str);
138}
139impl InstantExt for std::time::Instant {
140 fn print_elapsed(&self) {
141 let elapsed = self.elapsed();
142 println!("{elapsed:?}");
143 }
144 fn eprint_elapsed(&self) {
145 let elapsed = self.elapsed();
146 eprintln!("{elapsed:?}");
147 }
148 fn reset(&mut self) {
149 *self = std::time::Instant::now();
150 }
151 fn print_elapsed_with_msg(&self, msg: &str) {
152 let elapsed = self.elapsed();
153 println!("{msg} {elapsed:?}");
154 }
155 fn eprint_elapsed_with_msg(&self, msg: &str) {
156 let elapsed = self.elapsed();
157 eprintln!("{msg} {elapsed:?}");
158 }
159}
160impl InstantExt for std::time::SystemTime {
161 fn print_elapsed(&self) {
162 let elapsed = self.elapsed().unwrap_or_default();
163 println!("{elapsed:?}");
164 }
165 fn eprint_elapsed(&self) {
166 let elapsed = self.elapsed().unwrap_or_default();
167 eprintln!("{elapsed:?}");
168 }
169 fn reset(&mut self) {
170 *self = std::time::SystemTime::now();
171 }
172 fn print_elapsed_with_msg(&self, msg: &str) {
173 let elapsed = self.elapsed().unwrap_or_default();
174 println!("{msg} {elapsed:?}");
175 }
176 fn eprint_elapsed_with_msg(&self, msg: &str) {
177 let elapsed = self.elapsed().unwrap_or_default();
178 eprintln!("{msg} {elapsed:?}");
179 }
180}
181#[cfg(test)]
182mod tests {
183 use super::*;
184 #[test]
185 fn test_hms() {
186 let d = 1.hours() + 1.minutes() + 1.seconds() + 10.millis();
187 assert_eq!(d.hms(), "01:01:01");
188 assert_eq!(d.hmsxxx(), "01:01:01.010");
189 }
190}