1//! The [`Instant`] struct and its associated `impl`s.
23#![expect(deprecated)]
45use core::borrow::Borrow;
6use core::cmp::{Ord, Ordering, PartialEq, PartialOrd};
7use core::ops::{Add, AddAssign, Sub, SubAssign};
8use core::time::Durationas StdDuration;
9use std::time::Instantas StdInstant;
1011use crate::SignedDuration;
1213/// A measurement of a monotonically non-decreasing clock. Opaque and useful only with
14/// [`SignedDuration`].
15///
16/// Instants are always guaranteed to be no less than any previously measured instant when created,
17/// and are often useful for tasks such as measuring benchmarks or timing how long an operation
18/// takes.
19///
20/// Note, however, that instants are not guaranteed to be **steady**. In other words, each tick of
21/// the underlying clock may not be the same length (e.g. some seconds may be longer than others).
22/// An instant may jump forwards or experience time dilation (slow down or speed up), but it will
23/// never go backwards.
24///
25/// Instants are opaque types that can only be compared to one another. There is no method to get
26/// "the number of seconds" from an instant. Instead, it only allows measuring the duration between
27/// two instants (or comparing two instants).
28///
29/// This implementation allows for operations with signed [`SignedDuration`]s, but is otherwise
30/// identical to [`std::time::Instant`].
31#[doc(hidden)]
32#[deprecated(
33 since = "0.3.35",
34 note = "import `std::time::Instant` and `time::ext::InstantExt` instead"
35)]
36#[repr(transparent)]
37#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Instant {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Instant",
&&self.0)
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Instant {
#[inline]
fn clone(&self) -> Instant {
let _: ::core::clone::AssertParamIsClone<StdInstant>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Instant { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for Instant {
#[inline]
fn eq(&self, other: &Instant) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Instant {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<StdInstant>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Instant {
#[inline]
fn partial_cmp(&self, other: &Instant)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for Instant {
#[inline]
fn cmp(&self, other: &Instant) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.0, &other.0)
}
}Ord, #[automatically_derived]
impl ::core::hash::Hash for Instant {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash)]
38pub struct Instant(pub StdInstant);
3940impl Instant {
41/// Returns an `Instant` corresponding to "now".
42 ///
43 /// ```rust
44 /// # #![expect(deprecated)]
45 /// # use time::Instant;
46 /// println!("{:?}", Instant::now());
47 /// ```
48#[inline]
49pub fn now() -> Self {
50Self(StdInstant::now())
51 }
5253/// Returns the amount of time elapsed since this instant was created. The duration will always
54 /// be nonnegative if the instant is not synthetically created.
55 ///
56 /// ```rust
57 /// # #![expect(deprecated)]
58 /// # use time::{Instant, ext::{NumericalStdDuration, NumericalDuration}};
59 /// # use std::thread;
60 /// let instant = Instant::now();
61 /// thread::sleep(1.std_milliseconds());
62 /// assert!(instant.elapsed() >= 1.milliseconds());
63 /// ```
64#[inline]
65pub fn elapsed(self) -> SignedDuration {
66Self::now() - self67 }
6869/// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as
70 /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
71 /// otherwise.
72 ///
73 /// ```rust
74 /// # #![expect(deprecated)]
75 /// # use time::{Instant, ext::NumericalDuration};
76 /// let now = Instant::now();
77 /// assert_eq!(now.checked_add(5.seconds()), Some(now + 5.seconds()));
78 /// assert_eq!(now.checked_add((-5).seconds()), Some(now + (-5).seconds()));
79 /// ```
80#[inline]
81pub fn checked_add(self, duration: SignedDuration) -> Option<Self> {
82if duration.is_zero() {
83Some(self)
84 } else if duration.is_positive() {
85self.0.checked_add(duration.unsigned_abs()).map(Self)
86 } else {
87if true {
if !duration.is_negative() {
::core::panicking::panic("assertion failed: duration.is_negative()")
};
};debug_assert!(duration.is_negative());
88self.0.checked_sub(duration.unsigned_abs()).map(Self)
89 }
90 }
9192/// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as
93 /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
94 /// otherwise.
95 ///
96 /// ```rust
97 /// # #![expect(deprecated)]
98 /// # use time::{Instant, ext::NumericalDuration};
99 /// let now = Instant::now();
100 /// assert_eq!(now.checked_sub(5.seconds()), Some(now - 5.seconds()));
101 /// assert_eq!(now.checked_sub((-5).seconds()), Some(now - (-5).seconds()));
102 /// ```
103#[inline]
104pub fn checked_sub(self, duration: SignedDuration) -> Option<Self> {
105if duration.is_zero() {
106Some(self)
107 } else if duration.is_positive() {
108self.0.checked_sub(duration.unsigned_abs()).map(Self)
109 } else {
110if true {
if !duration.is_negative() {
::core::panicking::panic("assertion failed: duration.is_negative()")
};
};debug_assert!(duration.is_negative());
111self.0.checked_add(duration.unsigned_abs()).map(Self)
112 }
113 }
114115/// Obtain the inner [`std::time::Instant`].
116 ///
117 /// ```rust
118 /// # #![expect(deprecated)]
119 /// # use time::Instant;
120 /// let now = Instant::now();
121 /// assert_eq!(now.into_inner(), now.0);
122 /// ```
123#[inline]
124pub const fn into_inner(self) -> StdInstant {
125self.0
126}
127}
128129impl From<StdInstant> for Instant {
130#[inline]
131fn from(instant: StdInstant) -> Self {
132Self(instant)
133 }
134}
135136impl From<Instant> for StdInstant {
137#[inline]
138fn from(instant: Instant) -> Self {
139instant.0
140}
141}
142143impl Subfor Instant {
144type Output = SignedDuration;
145146/// # Panics
147 ///
148 /// This may panic if an overflow occurs.
149#[inline]
150fn sub(self, other: Self) -> Self::Output {
151match self.0.cmp(&other.0) {
152 Ordering::Equal => SignedDuration::ZERO,
153 Ordering::Greater => (self.0 - other.0)
154 .try_into()
155 .expect("overflow converting `std::time::Duration` to `time::SignedDuration`"),
156 Ordering::Less => -SignedDuration::try_from(other.0 - self.0)
157 .expect("overflow converting `std::time::Duration` to `time::SignedDuration`"),
158 }
159 }
160}
161162impl Sub<StdInstant> for Instant {
163type Output = SignedDuration;
164165#[inline]
166fn sub(self, other: StdInstant) -> Self::Output {
167self - Self(other)
168 }
169}
170171impl Sub<Instant> for StdInstant {
172type Output = SignedDuration;
173174#[inline]
175fn sub(self, other: Instant) -> Self::Output {
176Instant(self) - other177 }
178}
179180impl Add<SignedDuration> for Instant {
181type Output = Self;
182183/// # Panics
184 ///
185 /// This function may panic if the resulting point in time cannot be represented by the
186 /// underlying data structure.
187#[inline]
188fn add(self, duration: SignedDuration) -> Self::Output {
189if duration.is_positive() {
190Self(self.0 + duration.unsigned_abs())
191 } else if duration.is_negative() {
192#[expect(clippy::unchecked_time_subtraction)]
193Self(self.0 - duration.unsigned_abs())
194 } else {
195if true {
if !duration.is_zero() {
::core::panicking::panic("assertion failed: duration.is_zero()")
};
};debug_assert!(duration.is_zero());
196self197 }
198 }
199}
200201impl Add<SignedDuration> for StdInstant {
202type Output = Self;
203204/// # Panics
205 ///
206 /// This function may panic if the resulting point in time cannot be represented by the
207 /// underlying data structure.
208#[inline]
209fn add(self, duration: SignedDuration) -> Self::Output {
210 (Instant(self) + duration).0
211}
212}
213214impl Add<StdDuration> for Instant {
215type Output = Self;
216217/// # Panics
218 ///
219 /// This function may panic if the resulting point in time cannot be represented by the
220 /// underlying data structure.
221#[inline]
222fn add(self, duration: StdDuration) -> Self::Output {
223Self(self.0 + duration)
224 }
225}
226227impl AddAssign<SignedDuration> for Instant {
228/// # Panics
229 ///
230 /// This function may panic if the resulting point in time cannot be represented by the
231 /// underlying data structure.
232#[inline]
233fn add_assign(&mut self, rhs: SignedDuration) {
234*self = *self + rhs;
235 }
236}
237238impl AddAssign<StdDuration> for Instant {
239/// # Panics
240 ///
241 /// This function may panic if the resulting point in time cannot be represented by the
242 /// underlying data structure.
243#[inline]
244fn add_assign(&mut self, rhs: StdDuration) {
245*self = *self + rhs;
246 }
247}
248249impl AddAssign<SignedDuration> for StdInstant {
250/// # Panics
251 ///
252 /// This function may panic if the resulting point in time cannot be represented by the
253 /// underlying data structure.
254#[inline]
255fn add_assign(&mut self, rhs: SignedDuration) {
256*self = *self + rhs;
257 }
258}
259260impl Sub<SignedDuration> for Instant {
261type Output = Self;
262263/// # Panics
264 ///
265 /// This function may panic if the resulting point in time cannot be represented by the
266 /// underlying data structure.
267#[inline]
268fn sub(self, duration: SignedDuration) -> Self::Output {
269if duration.is_positive() {
270#[expect(clippy::unchecked_time_subtraction)]
271Self(self.0 - duration.unsigned_abs())
272 } else if duration.is_negative() {
273Self(self.0 + duration.unsigned_abs())
274 } else {
275if true {
if !duration.is_zero() {
::core::panicking::panic("assertion failed: duration.is_zero()")
};
};debug_assert!(duration.is_zero());
276self277 }
278 }
279}
280281impl Sub<SignedDuration> for StdInstant {
282type Output = Self;
283284/// # Panics
285 ///
286 /// This function may panic if the resulting point in time cannot be represented by the
287 /// underlying data structure.
288#[inline]
289fn sub(self, duration: SignedDuration) -> Self::Output {
290 (Instant(self) - duration).0
291}
292}
293294impl Sub<StdDuration> for Instant {
295type Output = Self;
296297/// # Panics
298 ///
299 /// This function may panic if the resulting point in time cannot be represented by the
300 /// underlying data structure.
301#[inline]
302fn sub(self, duration: StdDuration) -> Self::Output {
303#[expect(clippy::unchecked_time_subtraction)]
304Self(self.0 - duration)
305 }
306}
307308impl SubAssign<SignedDuration> for Instant {
309/// # Panics
310 ///
311 /// This function may panic if the resulting point in time cannot be represented by the
312 /// underlying data structure.
313#[inline]
314fn sub_assign(&mut self, rhs: SignedDuration) {
315*self = *self - rhs;
316 }
317}
318319impl SubAssign<StdDuration> for Instant {
320/// # Panics
321 ///
322 /// This function may panic if the resulting point in time cannot be represented by the
323 /// underlying data structure.
324#[inline]
325fn sub_assign(&mut self, rhs: StdDuration) {
326*self = *self - rhs;
327 }
328}
329330impl SubAssign<SignedDuration> for StdInstant {
331/// # Panics
332 ///
333 /// This function may panic if the resulting point in time cannot be represented by the
334 /// underlying data structure.
335#[inline]
336fn sub_assign(&mut self, rhs: SignedDuration) {
337*self = *self - rhs;
338 }
339}
340341impl PartialEq<StdInstant> for Instant {
342#[inline]
343fn eq(&self, rhs: &StdInstant) -> bool {
344self.0.eq(rhs)
345 }
346}
347348impl PartialEq<Instant> for StdInstant {
349#[inline]
350fn eq(&self, rhs: &Instant) -> bool {
351self.eq(&rhs.0)
352 }
353}
354355impl PartialOrd<StdInstant> for Instant {
356#[inline]
357fn partial_cmp(&self, rhs: &StdInstant) -> Option<Ordering> {
358self.0.partial_cmp(rhs)
359 }
360}
361362impl PartialOrd<Instant> for StdInstant {
363#[inline]
364fn partial_cmp(&self, rhs: &Instant) -> Option<Ordering> {
365self.partial_cmp(&rhs.0)
366 }
367}
368369impl AsRef<StdInstant> for Instant {
370#[inline]
371fn as_ref(&self) -> &StdInstant {
372&self.0
373}
374}
375376impl Borrow<StdInstant> for Instant {
377#[inline]
378fn borrow(&self) -> &StdInstant {
379&self.0
380}
381}