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::Duration;
1213/// A measurement of a monotonically non-decreasing clock. Opaque and useful only with [`Duration`].
14///
15/// Instants are always guaranteed to be no less than any previously measured instant when created,
16/// and are often useful for tasks such as measuring benchmarks or timing how long an operation
17/// takes.
18///
19/// Note, however, that instants are not guaranteed to be **steady**. In other words, each tick of
20/// the underlying clock may not be the same length (e.g. some seconds may be longer than others).
21/// An instant may jump forwards or experience time dilation (slow down or speed up), but it will
22/// never go backwards.
23///
24/// Instants are opaque types that can only be compared to one another. There is no method to get
25/// "the number of seconds" from an instant. Instead, it only allows measuring the duration between
26/// two instants (or comparing two instants).
27///
28/// This implementation allows for operations with signed [`Duration`]s, but is otherwise identical
29/// to [`std::time::Instant`].
30#[doc(hidden)]
31#[deprecated(
32 since = "0.3.35",
33 note = "import `std::time::Instant` and `time::ext::InstantExt` instead"
34)]
35#[repr(transparent)]
36#[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_receiver_is_total_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::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
}
}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)]
37pub struct Instant(pub StdInstant);
3839impl Instant {
40/// Returns an `Instant` corresponding to "now".
41 ///
42 /// ```rust
43 /// # #![expect(deprecated)]
44 /// # use time::Instant;
45 /// println!("{:?}", Instant::now());
46 /// ```
47#[inline]
48pub fn now() -> Self {
49Self(StdInstant::now())
50 }
5152/// Returns the amount of time elapsed since this instant was created. The duration will always
53 /// be nonnegative if the instant is not synthetically created.
54 ///
55 /// ```rust
56 /// # #![expect(deprecated)]
57 /// # use time::{Instant, ext::{NumericalStdDuration, NumericalDuration}};
58 /// # use std::thread;
59 /// let instant = Instant::now();
60 /// thread::sleep(1.std_milliseconds());
61 /// assert!(instant.elapsed() >= 1.milliseconds());
62 /// ```
63#[inline]
64pub fn elapsed(self) -> Duration {
65Self::now() - self66 }
6768/// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as
69 /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
70 /// otherwise.
71 ///
72 /// ```rust
73 /// # #![expect(deprecated)]
74 /// # use time::{Instant, ext::NumericalDuration};
75 /// let now = Instant::now();
76 /// assert_eq!(now.checked_add(5.seconds()), Some(now + 5.seconds()));
77 /// assert_eq!(now.checked_add((-5).seconds()), Some(now + (-5).seconds()));
78 /// ```
79#[inline]
80pub fn checked_add(self, duration: Duration) -> Option<Self> {
81if duration.is_zero() {
82Some(self)
83 } else if duration.is_positive() {
84self.0.checked_add(duration.unsigned_abs()).map(Self)
85 } else {
86if true {
if !duration.is_negative() {
::core::panicking::panic("assertion failed: duration.is_negative()")
};
};debug_assert!(duration.is_negative());
87self.0.checked_sub(duration.unsigned_abs()).map(Self)
88 }
89 }
9091/// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as
92 /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
93 /// otherwise.
94 ///
95 /// ```rust
96 /// # #![expect(deprecated)]
97 /// # use time::{Instant, ext::NumericalDuration};
98 /// let now = Instant::now();
99 /// assert_eq!(now.checked_sub(5.seconds()), Some(now - 5.seconds()));
100 /// assert_eq!(now.checked_sub((-5).seconds()), Some(now - (-5).seconds()));
101 /// ```
102#[inline]
103pub fn checked_sub(self, duration: Duration) -> Option<Self> {
104if duration.is_zero() {
105Some(self)
106 } else if duration.is_positive() {
107self.0.checked_sub(duration.unsigned_abs()).map(Self)
108 } else {
109if true {
if !duration.is_negative() {
::core::panicking::panic("assertion failed: duration.is_negative()")
};
};debug_assert!(duration.is_negative());
110self.0.checked_add(duration.unsigned_abs()).map(Self)
111 }
112 }
113114/// Obtain the inner [`std::time::Instant`].
115 ///
116 /// ```rust
117 /// # #![expect(deprecated)]
118 /// # use time::Instant;
119 /// let now = Instant::now();
120 /// assert_eq!(now.into_inner(), now.0);
121 /// ```
122#[inline]
123pub const fn into_inner(self) -> StdInstant {
124self.0
125}
126}
127128impl From<StdInstant> for Instant {
129#[inline]
130fn from(instant: StdInstant) -> Self {
131Self(instant)
132 }
133}
134135impl From<Instant> for StdInstant {
136#[inline]
137fn from(instant: Instant) -> Self {
138instant.0
139}
140}
141142impl Subfor Instant {
143type Output = Duration;
144145/// # Panics
146 ///
147 /// This may panic if an overflow occurs.
148#[inline]
149fn sub(self, other: Self) -> Self::Output {
150match self.0.cmp(&other.0) {
151 Ordering::Equal => Duration::ZERO,
152 Ordering::Greater => (self.0 - other.0)
153 .try_into()
154 .expect("overflow converting `std::time::Duration` to `time::Duration`"),
155 Ordering::Less => -Duration::try_from(other.0 - self.0)
156 .expect("overflow converting `std::time::Duration` to `time::Duration`"),
157 }
158 }
159}
160161impl Sub<StdInstant> for Instant {
162type Output = Duration;
163164#[inline]
165fn sub(self, other: StdInstant) -> Self::Output {
166self - Self(other)
167 }
168}
169170impl Sub<Instant> for StdInstant {
171type Output = Duration;
172173#[inline]
174fn sub(self, other: Instant) -> Self::Output {
175Instant(self) - other176 }
177}
178179impl Add<Duration> for Instant {
180type Output = Self;
181182/// # Panics
183 ///
184 /// This function may panic if the resulting point in time cannot be represented by the
185 /// underlying data structure.
186#[inline]
187fn add(self, duration: Duration) -> Self::Output {
188if duration.is_positive() {
189Self(self.0 + duration.unsigned_abs())
190 } else if duration.is_negative() {
191#[expect(clippy::unchecked_time_subtraction)]
192Self(self.0 - duration.unsigned_abs())
193 } else {
194if true {
if !duration.is_zero() {
::core::panicking::panic("assertion failed: duration.is_zero()")
};
};debug_assert!(duration.is_zero());
195self196 }
197 }
198}
199200impl Add<Duration> for StdInstant {
201type Output = Self;
202203/// # Panics
204 ///
205 /// This function may panic if the resulting point in time cannot be represented by the
206 /// underlying data structure.
207#[inline]
208fn add(self, duration: Duration) -> Self::Output {
209 (Instant(self) + duration).0
210}
211}
212213impl Add<StdDuration> for Instant {
214type Output = Self;
215216/// # Panics
217 ///
218 /// This function may panic if the resulting point in time cannot be represented by the
219 /// underlying data structure.
220#[inline]
221fn add(self, duration: StdDuration) -> Self::Output {
222Self(self.0 + duration)
223 }
224}
225226impl AddAssign<Duration> for Instant {
227/// # Panics
228 ///
229 /// This function may panic if the resulting point in time cannot be represented by the
230 /// underlying data structure.
231#[inline]
232fn add_assign(&mut self, rhs: Duration) {
233*self = *self + rhs;
234 }
235}
236237impl AddAssign<StdDuration> for Instant {
238/// # Panics
239 ///
240 /// This function may panic if the resulting point in time cannot be represented by the
241 /// underlying data structure.
242#[inline]
243fn add_assign(&mut self, rhs: StdDuration) {
244*self = *self + rhs;
245 }
246}
247248impl AddAssign<Duration> for StdInstant {
249/// # Panics
250 ///
251 /// This function may panic if the resulting point in time cannot be represented by the
252 /// underlying data structure.
253#[inline]
254fn add_assign(&mut self, rhs: Duration) {
255*self = *self + rhs;
256 }
257}
258259impl Sub<Duration> for Instant {
260type Output = Self;
261262/// # Panics
263 ///
264 /// This function may panic if the resulting point in time cannot be represented by the
265 /// underlying data structure.
266#[inline]
267fn sub(self, duration: Duration) -> Self::Output {
268if duration.is_positive() {
269#[expect(clippy::unchecked_time_subtraction)]
270Self(self.0 - duration.unsigned_abs())
271 } else if duration.is_negative() {
272Self(self.0 + duration.unsigned_abs())
273 } else {
274if true {
if !duration.is_zero() {
::core::panicking::panic("assertion failed: duration.is_zero()")
};
};debug_assert!(duration.is_zero());
275self276 }
277 }
278}
279280impl Sub<Duration> for StdInstant {
281type Output = Self;
282283/// # Panics
284 ///
285 /// This function may panic if the resulting point in time cannot be represented by the
286 /// underlying data structure.
287#[inline]
288fn sub(self, duration: Duration) -> Self::Output {
289 (Instant(self) - duration).0
290}
291}
292293impl Sub<StdDuration> for Instant {
294type Output = Self;
295296/// # Panics
297 ///
298 /// This function may panic if the resulting point in time cannot be represented by the
299 /// underlying data structure.
300#[inline]
301fn sub(self, duration: StdDuration) -> Self::Output {
302#[expect(clippy::unchecked_time_subtraction)]
303Self(self.0 - duration)
304 }
305}
306307impl SubAssign<Duration> for Instant {
308/// # Panics
309 ///
310 /// This function may panic if the resulting point in time cannot be represented by the
311 /// underlying data structure.
312#[inline]
313fn sub_assign(&mut self, rhs: Duration) {
314*self = *self - rhs;
315 }
316}
317318impl SubAssign<StdDuration> for Instant {
319/// # Panics
320 ///
321 /// This function may panic if the resulting point in time cannot be represented by the
322 /// underlying data structure.
323#[inline]
324fn sub_assign(&mut self, rhs: StdDuration) {
325*self = *self - rhs;
326 }
327}
328329impl SubAssign<Duration> for StdInstant {
330/// # Panics
331 ///
332 /// This function may panic if the resulting point in time cannot be represented by the
333 /// underlying data structure.
334#[inline]
335fn sub_assign(&mut self, rhs: Duration) {
336*self = *self - rhs;
337 }
338}
339340impl PartialEq<StdInstant> for Instant {
341#[inline]
342fn eq(&self, rhs: &StdInstant) -> bool {
343self.0.eq(rhs)
344 }
345}
346347impl PartialEq<Instant> for StdInstant {
348#[inline]
349fn eq(&self, rhs: &Instant) -> bool {
350self.eq(&rhs.0)
351 }
352}
353354impl PartialOrd<StdInstant> for Instant {
355#[inline]
356fn partial_cmp(&self, rhs: &StdInstant) -> Option<Ordering> {
357self.0.partial_cmp(rhs)
358 }
359}
360361impl PartialOrd<Instant> for StdInstant {
362#[inline]
363fn partial_cmp(&self, rhs: &Instant) -> Option<Ordering> {
364self.partial_cmp(&rhs.0)
365 }
366}
367368impl AsRef<StdInstant> for Instant {
369#[inline]
370fn as_ref(&self) -> &StdInstant {
371&self.0
372}
373}
374375impl Borrow<StdInstant> for Instant {
376#[inline]
377fn borrow(&self) -> &StdInstant {
378&self.0
379}
380}