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.
71     ///
72     /// # Panics
73     ///
74     /// This function will panic if `earlier` is later than `self`.
duration_since(&self, earlier: Instant) -> Duration75     pub fn duration_since(&self, earlier: Instant) -> Duration {
76         self.std.duration_since(earlier.std)
77     }
78 
79     /// Returns the amount of time elapsed from another instant to this one, or
80     /// None if that instant is later than this one.
81     ///
82     /// # Examples
83     ///
84     /// ```
85     /// use tokio::time::{Duration, Instant, sleep};
86     ///
87     /// #[tokio::main]
88     /// async fn main() {
89     ///     let now = Instant::now();
90     ///     sleep(Duration::new(1, 0)).await;
91     ///     let new_now = Instant::now();
92     ///     println!("{:?}", new_now.checked_duration_since(now));
93     ///     println!("{:?}", now.checked_duration_since(new_now)); // None
94     /// }
95     /// ```
checked_duration_since(&self, earlier: Instant) -> Option<Duration>96     pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
97         self.std.checked_duration_since(earlier.std)
98     }
99 
100     /// Returns the amount of time elapsed from another instant to this one, or
101     /// zero duration if that instant is later than this one.
102     ///
103     /// # Examples
104     ///
105     /// ```
106     /// use tokio::time::{Duration, Instant, sleep};
107     ///
108     /// #[tokio::main]
109     /// async fn main() {
110     ///     let now = Instant::now();
111     ///     sleep(Duration::new(1, 0)).await;
112     ///     let new_now = Instant::now();
113     ///     println!("{:?}", new_now.saturating_duration_since(now));
114     ///     println!("{:?}", now.saturating_duration_since(new_now)); // 0ns
115     /// }
116     /// ```
saturating_duration_since(&self, earlier: Instant) -> Duration117     pub fn saturating_duration_since(&self, earlier: Instant) -> Duration {
118         self.std.saturating_duration_since(earlier.std)
119     }
120 
121     /// Returns the amount of time elapsed since this instant was created.
122     ///
123     /// # Panics
124     ///
125     /// This function may panic if the current time is earlier than this
126     /// instant, which is something that can happen if an `Instant` is
127     /// produced synthetically.
128     ///
129     /// # Examples
130     ///
131     /// ```
132     /// use tokio::time::{Duration, Instant, sleep};
133     ///
134     /// #[tokio::main]
135     /// async fn main() {
136     ///     let instant = Instant::now();
137     ///     let three_secs = Duration::from_secs(3);
138     ///     sleep(three_secs).await;
139     ///     assert!(instant.elapsed() >= three_secs);
140     /// }
141     /// ```
elapsed(&self) -> Duration142     pub fn elapsed(&self) -> Duration {
143         Instant::now() - *self
144     }
145 
146     /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be
147     /// represented as `Instant` (which means it's inside the bounds of the
148     /// underlying data structure), `None` otherwise.
checked_add(&self, duration: Duration) -> Option<Instant>149     pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
150         self.std.checked_add(duration).map(Instant::from_std)
151     }
152 
153     /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be
154     /// represented as `Instant` (which means it's inside the bounds of the
155     /// underlying data structure), `None` otherwise.
checked_sub(&self, duration: Duration) -> Option<Instant>156     pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
157         self.std.checked_sub(duration).map(Instant::from_std)
158     }
159 }
160 
161 impl From<std::time::Instant> for Instant {
from(time: std::time::Instant) -> Instant162     fn from(time: std::time::Instant) -> Instant {
163         Instant::from_std(time)
164     }
165 }
166 
167 impl From<Instant> for std::time::Instant {
from(time: Instant) -> std::time::Instant168     fn from(time: Instant) -> std::time::Instant {
169         time.into_std()
170     }
171 }
172 
173 impl ops::Add<Duration> for Instant {
174     type Output = Instant;
175 
add(self, other: Duration) -> Instant176     fn add(self, other: Duration) -> Instant {
177         Instant::from_std(self.std + other)
178     }
179 }
180 
181 impl ops::AddAssign<Duration> for Instant {
add_assign(&mut self, rhs: Duration)182     fn add_assign(&mut self, rhs: Duration) {
183         *self = *self + rhs;
184     }
185 }
186 
187 impl ops::Sub for Instant {
188     type Output = Duration;
189 
sub(self, rhs: Instant) -> Duration190     fn sub(self, rhs: Instant) -> Duration {
191         self.std - rhs.std
192     }
193 }
194 
195 impl ops::Sub<Duration> for Instant {
196     type Output = Instant;
197 
sub(self, rhs: Duration) -> Instant198     fn sub(self, rhs: Duration) -> Instant {
199         Instant::from_std(self.std - rhs)
200     }
201 }
202 
203 impl ops::SubAssign<Duration> for Instant {
sub_assign(&mut self, rhs: Duration)204     fn sub_assign(&mut self, rhs: Duration) {
205         *self = *self - rhs;
206     }
207 }
208 
209 impl fmt::Debug for Instant {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result210     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
211         self.std.fmt(fmt)
212     }
213 }
214 
215 #[cfg(not(feature = "test-util"))]
216 mod variant {
217     use super::Instant;
218 
now() -> Instant219     pub(super) fn now() -> Instant {
220         Instant::from_std(std::time::Instant::now())
221     }
222 }
223 
224 #[cfg(feature = "test-util")]
225 mod variant {
226     use super::Instant;
227 
now() -> Instant228     pub(super) fn now() -> Instant {
229         crate::time::clock::now()
230     }
231 }
232