1 #![allow(clippy::trivially_copy_pass_by_ref)]
2 
3 use std::fmt;
4 use std::ops;
5 use std::time::Duration;
6 
7 /// A measurement of a monotonically nondecreasing clock.
8 /// Opaque and useful only with `Duration`.
9 ///
10 /// Instants are always guaranteed to be no less than any previously measured
11 /// instant when created, and are often useful for tasks such as measuring
12 /// benchmarks or timing how long an operation takes.
13 ///
14 /// Note, however, that instants are not guaranteed to be **steady**. In other
15 /// words, each tick of the underlying clock may not be the same length (e.g.
16 /// some seconds may be longer than others). An instant may jump forwards or
17 /// experience time dilation (slow down or speed up), but it will never go
18 /// backwards.
19 ///
20 /// Instants are opaque types that can only be compared to one another. There is
21 /// no method to get "the number of seconds" from an instant. Instead, it only
22 /// allows measuring the duration between two instants (or comparing two
23 /// instants).
24 ///
25 /// The size of an `Instant` struct may vary depending on the target operating
26 /// system.
27 ///
28 /// # Note
29 ///
30 /// This type wraps the inner `std` variant and is used to align the Tokio
31 /// clock for uses of `now()`. This can be useful for testing where you can
32 /// take advantage of `time::pause()` and `time::advance()`.
33 #[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)]
34 pub struct Instant {
35     std: std::time::Instant,
36 }
37 
38 impl Instant {
39     /// Returns an instant corresponding to "now".
40     ///
41     /// # Examples
42     ///
43     /// ```
44     /// use tokio::time::Instant;
45     ///
46     /// let now = Instant::now();
47     /// ```
now() -> Instant48     pub fn now() -> Instant {
49         variant::now()
50     }
51 
52     /// Create a `tokio::time::Instant` from a `std::time::Instant`.
from_std(std: std::time::Instant) -> Instant53     pub fn from_std(std: std::time::Instant) -> Instant {
54         Instant { std }
55     }
56 
far_future() -> Instant57     pub(crate) fn far_future() -> Instant {
58         // Roughly 30 years from now.
59         // API does not provide a way to obtain max `Instant`
60         // or convert specific date in the future to instant.
61         // 1000 years overflows on macOS, 100 years overflows on FreeBSD.
62         Self::now() + Duration::from_secs(86400 * 365 * 30)
63     }
64 
65     /// Convert the value into a `std::time::Instant`.
into_std(self) -> std::time::Instant66     pub fn into_std(self) -> std::time::Instant {
67         self.std
68     }
69 
70     /// Returns the amount of time elapsed from another instant to this one, or
71     /// zero duration if that instant is later than this one.
duration_since(&self, earlier: Instant) -> Duration72     pub fn duration_since(&self, earlier: Instant) -> Duration {
73         self.std.saturating_duration_since(earlier.std)
74     }
75 
76     /// Returns the amount of time elapsed from another instant to this one, or
77     /// None if that instant is later than this one.
78     ///
79     /// # Examples
80     ///
81     /// ```
82     /// use tokio::time::{Duration, Instant, sleep};
83     ///
84     /// #[tokio::main]
85     /// async fn main() {
86     ///     let now = Instant::now();
87     ///     sleep(Duration::new(1, 0)).await;
88     ///     let new_now = Instant::now();
89     ///     println!("{:?}", new_now.checked_duration_since(now));
90     ///     println!("{:?}", now.checked_duration_since(new_now)); // None
91     /// }
92     /// ```
checked_duration_since(&self, earlier: Instant) -> Option<Duration>93     pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
94         self.std.checked_duration_since(earlier.std)
95     }
96 
97     /// Returns the amount of time elapsed from another instant to this one, or
98     /// zero duration if that instant is later than this one.
99     ///
100     /// # Examples
101     ///
102     /// ```
103     /// use tokio::time::{Duration, Instant, sleep};
104     ///
105     /// #[tokio::main]
106     /// async fn main() {
107     ///     let now = Instant::now();
108     ///     sleep(Duration::new(1, 0)).await;
109     ///     let new_now = Instant::now();
110     ///     println!("{:?}", new_now.saturating_duration_since(now));
111     ///     println!("{:?}", now.saturating_duration_since(new_now)); // 0ns
112     /// }
113     /// ```
saturating_duration_since(&self, earlier: Instant) -> Duration114     pub fn saturating_duration_since(&self, earlier: Instant) -> Duration {
115         self.std.saturating_duration_since(earlier.std)
116     }
117 
118     /// Returns the amount of time elapsed since this instant was created,
119     /// or zero duration if this instant is in the future.
120     ///
121     /// # Examples
122     ///
123     /// ```
124     /// use tokio::time::{Duration, Instant, sleep};
125     ///
126     /// #[tokio::main]
127     /// async fn main() {
128     ///     let instant = Instant::now();
129     ///     let three_secs = Duration::from_secs(3);
130     ///     sleep(three_secs).await;
131     ///     assert!(instant.elapsed() >= three_secs);
132     /// }
133     /// ```
elapsed(&self) -> Duration134     pub fn elapsed(&self) -> Duration {
135         Instant::now().saturating_duration_since(*self)
136     }
137 
138     /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be
139     /// represented as `Instant` (which means it's inside the bounds of the
140     /// underlying data structure), `None` otherwise.
checked_add(&self, duration: Duration) -> Option<Instant>141     pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
142         self.std.checked_add(duration).map(Instant::from_std)
143     }
144 
145     /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be
146     /// represented as `Instant` (which means it's inside the bounds of the
147     /// underlying data structure), `None` otherwise.
checked_sub(&self, duration: Duration) -> Option<Instant>148     pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
149         self.std.checked_sub(duration).map(Instant::from_std)
150     }
151 }
152 
153 impl From<std::time::Instant> for Instant {
from(time: std::time::Instant) -> Instant154     fn from(time: std::time::Instant) -> Instant {
155         Instant::from_std(time)
156     }
157 }
158 
159 impl From<Instant> for std::time::Instant {
from(time: Instant) -> std::time::Instant160     fn from(time: Instant) -> std::time::Instant {
161         time.into_std()
162     }
163 }
164 
165 impl ops::Add<Duration> for Instant {
166     type Output = Instant;
167 
add(self, other: Duration) -> Instant168     fn add(self, other: Duration) -> Instant {
169         Instant::from_std(self.std + other)
170     }
171 }
172 
173 impl ops::AddAssign<Duration> for Instant {
add_assign(&mut self, rhs: Duration)174     fn add_assign(&mut self, rhs: Duration) {
175         *self = *self + rhs;
176     }
177 }
178 
179 impl ops::Sub for Instant {
180     type Output = Duration;
181 
sub(self, rhs: Instant) -> Duration182     fn sub(self, rhs: Instant) -> Duration {
183         self.std.saturating_duration_since(rhs.std)
184     }
185 }
186 
187 impl ops::Sub<Duration> for Instant {
188     type Output = Instant;
189 
sub(self, rhs: Duration) -> Instant190     fn sub(self, rhs: Duration) -> Instant {
191         Instant::from_std(std::time::Instant::sub(self.std, rhs))
192     }
193 }
194 
195 impl ops::SubAssign<Duration> for Instant {
sub_assign(&mut self, rhs: Duration)196     fn sub_assign(&mut self, rhs: Duration) {
197         *self = *self - rhs;
198     }
199 }
200 
201 impl fmt::Debug for Instant {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result202     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
203         self.std.fmt(fmt)
204     }
205 }
206 
207 #[cfg(not(feature = "test-util"))]
208 mod variant {
209     use super::Instant;
210 
now() -> Instant211     pub(super) fn now() -> Instant {
212         Instant::from_std(std::time::Instant::now())
213     }
214 }
215 
216 #[cfg(feature = "test-util")]
217 mod variant {
218     use super::Instant;
219 
now() -> Instant220     pub(super) fn now() -> Instant {
221         crate::time::clock::now()
222     }
223 }
224