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    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`.
66    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.
72    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    /// ```
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    /// ```
114    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 that 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    /// ```
134    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.
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.
148    pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
149        self.std.checked_sub(duration).map(Instant::from_std)
150    }
151}
152
153impl From<std::time::Instant> for Instant {
154    fn from(time: std::time::Instant) -> Instant {
155        Instant::from_std(time)
156    }
157}
158
159impl From<Instant> for std::time::Instant {
160    fn from(time: Instant) -> std::time::Instant {
161        time.into_std()
162    }
163}
164
165impl ops::Add<Duration> for Instant {
166    type Output = Instant;
167
168    fn add(self, other: Duration) -> Instant {
169        Instant::from_std(self.std + other)
170    }
171}
172
173impl ops::AddAssign<Duration> for Instant {
174    fn add_assign(&mut self, rhs: Duration) {
175        *self = *self + rhs;
176    }
177}
178
179impl ops::Sub for Instant {
180    type Output = Duration;
181
182    fn sub(self, rhs: Instant) -> Duration {
183        self.std.saturating_duration_since(rhs.std)
184    }
185}
186
187impl ops::Sub<Duration> for Instant {
188    type Output = Instant;
189
190    fn sub(self, rhs: Duration) -> Instant {
191        Instant::from_std(std::time::Instant::sub(self.std, rhs))
192    }
193}
194
195impl ops::SubAssign<Duration> for Instant {
196    fn sub_assign(&mut self, rhs: Duration) {
197        *self = *self - rhs;
198    }
199}
200
201impl fmt::Debug for Instant {
202    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
203        self.std.fmt(fmt)
204    }
205}
206
207#[cfg(not(feature = "test-util"))]
208mod variant {
209    use super::Instant;
210
211    pub(super) fn now() -> Instant {
212        Instant::from_std(std::time::Instant::now())
213    }
214}
215
216#[cfg(feature = "test-util")]
217mod variant {
218    use super::Instant;
219
220    pub(super) fn now() -> Instant {
221        crate::time::clock::now()
222    }
223}