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