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