tokio/time/instant.rs
1#![allow(clippy::trivially_copy_pass_by_ref)]
2
3use std::fmt;
4use std::ops;
5use 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)]
34pub struct Instant {
35 std: std::time::Instant,
36}
37
38impl 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 /// ```
48 pub fn now() -> Instant {
49 variant::now()
50 }
51
52 /// Create a `tokio::time::Instant` from a `std::time::Instant`.
53 pub fn from_std(std: std::time::Instant) -> Instant {
54 Instant { std }
55 }
56
57 /// Convert the value into a `std::time::Instant`.
58 pub fn into_std(self) -> std::time::Instant {
59 self.std
60 }
61
62 /// Returns the amount of time elapsed from another instant to this one, or
63 /// zero duration if that instant is later than this one.
64 pub fn duration_since(&self, earlier: Instant) -> Duration {
65 self.std.saturating_duration_since(earlier.std)
66 }
67
68 /// Returns the amount of time elapsed from another instant to this one, or
69 /// None if that instant is later than this one.
70 ///
71 /// # Examples
72 ///
73 /// ```
74 /// use tokio::time::{Duration, Instant, sleep};
75 ///
76 /// # #[tokio::main(flavor = "current_thread")]
77 /// # async fn main() {
78 /// let now = Instant::now();
79 /// sleep(Duration::new(1, 0)).await;
80 /// let new_now = Instant::now();
81 /// println!("{:?}", new_now.checked_duration_since(now));
82 /// println!("{:?}", now.checked_duration_since(new_now)); // None
83 /// # }
84 /// ```
85 pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
86 self.std.checked_duration_since(earlier.std)
87 }
88
89 /// Returns the amount of time elapsed from another instant to this one, or
90 /// zero duration if that instant is later than this one.
91 ///
92 /// # Examples
93 ///
94 /// ```
95 /// use tokio::time::{Duration, Instant, sleep};
96 ///
97 /// # #[tokio::main(flavor = "current_thread")]
98 /// # async fn main() {
99 /// let now = Instant::now();
100 /// sleep(Duration::new(1, 0)).await;
101 /// let new_now = Instant::now();
102 /// println!("{:?}", new_now.saturating_duration_since(now));
103 /// println!("{:?}", now.saturating_duration_since(new_now)); // 0ns
104 /// # }
105 /// ```
106 pub fn saturating_duration_since(&self, earlier: Instant) -> Duration {
107 self.std.saturating_duration_since(earlier.std)
108 }
109
110 /// Returns the amount of time elapsed since this instant was created,
111 /// or zero duration if this instant is in the future.
112 ///
113 /// # Examples
114 ///
115 /// ```
116 /// use tokio::time::{Duration, Instant, sleep};
117 ///
118 /// # #[tokio::main(flavor = "current_thread")]
119 /// # async fn main() {
120 /// let instant = Instant::now();
121 /// let three_secs = Duration::from_secs(3);
122 /// sleep(three_secs).await;
123 /// assert!(instant.elapsed() >= three_secs);
124 /// # }
125 /// ```
126 pub fn elapsed(&self) -> Duration {
127 Instant::now().saturating_duration_since(*self)
128 }
129
130 /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be
131 /// represented as `Instant` (which means it's inside the bounds of the
132 /// underlying data structure), `None` otherwise.
133 pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
134 self.std.checked_add(duration).map(Instant::from_std)
135 }
136
137 /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be
138 /// represented as `Instant` (which means it's inside the bounds of the
139 /// underlying data structure), `None` otherwise.
140 pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
141 self.std.checked_sub(duration).map(Instant::from_std)
142 }
143}
144
145impl From<std::time::Instant> for Instant {
146 fn from(time: std::time::Instant) -> Instant {
147 Instant::from_std(time)
148 }
149}
150
151impl From<Instant> for std::time::Instant {
152 fn from(time: Instant) -> std::time::Instant {
153 time.into_std()
154 }
155}
156
157impl ops::Add<Duration> for Instant {
158 type Output = Instant;
159
160 fn add(self, other: Duration) -> Instant {
161 Instant::from_std(self.std + other)
162 }
163}
164
165impl ops::AddAssign<Duration> for Instant {
166 fn add_assign(&mut self, rhs: Duration) {
167 *self = *self + rhs;
168 }
169}
170
171impl ops::Sub for Instant {
172 type Output = Duration;
173
174 fn sub(self, rhs: Instant) -> Duration {
175 self.std.saturating_duration_since(rhs.std)
176 }
177}
178
179impl ops::Sub<Duration> for Instant {
180 type Output = Instant;
181
182 fn sub(self, rhs: Duration) -> Instant {
183 Instant::from_std(std::time::Instant::sub(self.std, rhs))
184 }
185}
186
187impl ops::SubAssign<Duration> for Instant {
188 fn sub_assign(&mut self, rhs: Duration) {
189 *self = *self - rhs;
190 }
191}
192
193impl fmt::Debug for Instant {
194 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
195 self.std.fmt(fmt)
196 }
197}
198
199#[cfg(not(feature = "test-util"))]
200mod variant {
201 use super::Instant;
202
203 pub(super) fn now() -> Instant {
204 Instant::from_std(std::time::Instant::now())
205 }
206}
207
208#[cfg(feature = "test-util")]
209mod variant {
210 use super::Instant;
211
212 pub(super) fn now() -> Instant {
213 crate::time::clock::now()
214 }
215}