time/
utc_date_time.rs

1//! The [`UtcDateTime`] struct and associated `impl`s.
2
3#[cfg(feature = "formatting")]
4use alloc::string::String;
5use core::fmt;
6use core::ops::{Add, AddAssign, Sub, SubAssign};
7use core::time::Duration as StdDuration;
8#[cfg(feature = "formatting")]
9use std::io;
10
11use deranged::RangedI64;
12use powerfmt::ext::FormatterExt as _;
13use powerfmt::smart_display::{self, FormatterOptions, Metadata, SmartDisplay};
14
15use crate::convert::*;
16use crate::date::{MAX_YEAR, MIN_YEAR};
17#[cfg(feature = "formatting")]
18use crate::formatting::Formattable;
19use crate::internal_macros::{
20    cascade, const_try, const_try_opt, div_floor, ensure_ranged, expect_opt,
21};
22#[cfg(feature = "parsing")]
23use crate::parsing::Parsable;
24use crate::{
25    error, util, Date, Duration, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset, Weekday,
26};
27
28/// The Julian day of the Unix epoch.
29const UNIX_EPOCH_JULIAN_DAY: i32 = UtcDateTime::UNIX_EPOCH.to_julian_day();
30
31/// A [`PrimitiveDateTime`] that is known to be UTC.
32///
33/// `UtcDateTime` is guaranteed to be ABI-compatible with [`PrimitiveDateTime`], meaning that
34/// transmuting from one to the other will not result in undefined behavior.
35#[repr(transparent)]
36#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
37pub struct UtcDateTime {
38    inner: PrimitiveDateTime,
39}
40
41impl UtcDateTime {
42    /// Midnight, 1 January, 1970.
43    ///
44    /// ```rust
45    /// # use time::UtcDateTime;
46    /// # use time_macros::utc_datetime;
47    /// assert_eq!(UtcDateTime::UNIX_EPOCH, utc_datetime!(1970-01-01 0:00));
48    /// ```
49    pub const UNIX_EPOCH: Self = Self::new(
50        // Safety: `ordinal` is not zero.
51        unsafe { Date::__from_ordinal_date_unchecked(1970, 1) },
52        Time::MIDNIGHT,
53    );
54
55    /// The smallest value that can be represented by `UtcDateTime`.
56    ///
57    /// Depending on `large-dates` feature flag, value of this constant may vary.
58    ///
59    /// 1. With `large-dates` disabled it is equal to `-9999-01-01 00:00:00.0`
60    /// 2. With `large-dates` enabled it is equal to `-999999-01-01 00:00:00.0`
61    ///
62    /// ```rust
63    /// # use time::UtcDateTime;
64    /// # use time_macros::utc_datetime;
65    #[cfg_attr(
66        feature = "large-dates",
67        doc = "// Assuming `large-dates` feature is enabled."
68    )]
69    #[cfg_attr(
70        feature = "large-dates",
71        doc = "assert_eq!(UtcDateTime::MIN, utc_datetime!(-999999-01-01 0:00));"
72    )]
73    #[cfg_attr(
74        not(feature = "large-dates"),
75        doc = "// Assuming `large-dates` feature is disabled."
76    )]
77    #[cfg_attr(
78        not(feature = "large-dates"),
79        doc = "assert_eq!(UtcDateTime::MIN, utc_datetime!(-9999-01-01 0:00));"
80    )]
81    /// ```
82    pub const MIN: Self = Self::new(Date::MIN, Time::MIDNIGHT);
83
84    /// The largest value that can be represented by `UtcDateTime`.
85    ///
86    /// Depending on `large-dates` feature flag, value of this constant may vary.
87    ///
88    /// 1. With `large-dates` disabled it is equal to `9999-12-31 23:59:59.999_999_999`
89    /// 2. With `large-dates` enabled it is equal to `999999-12-31 23:59:59.999_999_999`
90    ///
91    /// ```rust
92    /// # use time::UtcDateTime;
93    /// # use time_macros::utc_datetime;
94    #[cfg_attr(
95        feature = "large-dates",
96        doc = "// Assuming `large-dates` feature is enabled."
97    )]
98    #[cfg_attr(
99        feature = "large-dates",
100        doc = "assert_eq!(UtcDateTime::MAX, utc_datetime!(+999999-12-31 23:59:59.999_999_999));"
101    )]
102    #[cfg_attr(
103        not(feature = "large-dates"),
104        doc = "// Assuming `large-dates` feature is disabled."
105    )]
106    #[cfg_attr(
107        not(feature = "large-dates"),
108        doc = "assert_eq!(UtcDateTime::MAX, utc_datetime!(+9999-12-31 23:59:59.999_999_999));"
109    )]
110    /// ```
111    pub const MAX: Self = Self::new(Date::MAX, Time::MAX);
112
113    /// Create a new `UtcDateTime` with the current date and time.
114    ///
115    /// ```rust
116    /// # use time::UtcDateTime;
117    /// assert!(UtcDateTime::now().year() >= 2019);
118    /// ```
119    #[cfg(feature = "std")]
120    pub fn now() -> Self {
121        #[cfg(all(
122            target_family = "wasm",
123            not(any(target_os = "emscripten", target_os = "wasi")),
124            feature = "wasm-bindgen"
125        ))]
126        {
127            js_sys::Date::new_0().into()
128        }
129
130        #[cfg(not(all(
131            target_family = "wasm",
132            not(any(target_os = "emscripten", target_os = "wasi")),
133            feature = "wasm-bindgen"
134        )))]
135        std::time::SystemTime::now().into()
136    }
137
138    /// Create a new `UtcDateTime` from the provided [`Date`] and [`Time`].
139    ///
140    /// ```rust
141    /// # use time::UtcDateTime;
142    /// # use time_macros::{date, utc_datetime, time};
143    /// assert_eq!(
144    ///     UtcDateTime::new(date!(2019-01-01), time!(0:00)),
145    ///     utc_datetime!(2019-01-01 0:00),
146    /// );
147    /// ```
148    pub const fn new(date: Date, time: Time) -> Self {
149        Self {
150            inner: PrimitiveDateTime::new(date, time),
151        }
152    }
153
154    /// Create a new `UtcDateTime` from the [`PrimitiveDateTime`], assuming that the latter is UTC.
155    pub(crate) const fn from_primitive(date_time: PrimitiveDateTime) -> Self {
156        Self { inner: date_time }
157    }
158
159    /// Obtain the [`PrimitiveDateTime`] that this `UtcDateTime` represents. The no-longer-attached
160    /// [`UtcOffset`] is assumed to be UTC.
161    pub(crate) const fn as_primitive(self) -> PrimitiveDateTime {
162        self.inner
163    }
164
165    /// Create a `UtcDateTime` from the provided Unix timestamp.
166    ///
167    /// ```rust
168    /// # use time::UtcDateTime;
169    /// # use time_macros::utc_datetime;
170    /// assert_eq!(
171    ///     UtcDateTime::from_unix_timestamp(0),
172    ///     Ok(UtcDateTime::UNIX_EPOCH),
173    /// );
174    /// assert_eq!(
175    ///     UtcDateTime::from_unix_timestamp(1_546_300_800),
176    ///     Ok(utc_datetime!(2019-01-01 0:00)),
177    /// );
178    /// ```
179    ///
180    /// If you have a timestamp-nanosecond pair, you can use something along the lines of the
181    /// following:
182    ///
183    /// ```rust
184    /// # use time::{Duration, UtcDateTime, ext::NumericalDuration};
185    /// let (timestamp, nanos) = (1, 500_000_000);
186    /// assert_eq!(
187    ///     UtcDateTime::from_unix_timestamp(timestamp)? + Duration::nanoseconds(nanos),
188    ///     UtcDateTime::UNIX_EPOCH + 1.5.seconds()
189    /// );
190    /// # Ok::<_, time::Error>(())
191    /// ```
192    pub const fn from_unix_timestamp(timestamp: i64) -> Result<Self, error::ComponentRange> {
193        type Timestamp =
194            RangedI64<{ UtcDateTime::MIN.unix_timestamp() }, { UtcDateTime::MAX.unix_timestamp() }>;
195        ensure_ranged!(Timestamp: timestamp);
196
197        // Use the unchecked method here, as the input validity has already been verified.
198        // Safety: The Julian day number is in range.
199        let date = unsafe {
200            Date::from_julian_day_unchecked(
201                UNIX_EPOCH_JULIAN_DAY + div_floor!(timestamp, Second::per(Day) as i64) as i32,
202            )
203        };
204
205        let seconds_within_day = timestamp.rem_euclid(Second::per(Day) as i64);
206        // Safety: All values are in range.
207        let time = unsafe {
208            Time::__from_hms_nanos_unchecked(
209                (seconds_within_day / Second::per(Hour) as i64) as u8,
210                ((seconds_within_day % Second::per(Hour) as i64) / Minute::per(Hour) as i64) as u8,
211                (seconds_within_day % Second::per(Minute) as i64) as u8,
212                0,
213            )
214        };
215
216        Ok(Self::new(date, time))
217    }
218
219    /// Construct an `UtcDateTime` from the provided Unix timestamp (in nanoseconds).
220    ///
221    /// ```rust
222    /// # use time::UtcDateTime;
223    /// # use time_macros::utc_datetime;
224    /// assert_eq!(
225    ///     UtcDateTime::from_unix_timestamp_nanos(0),
226    ///     Ok(UtcDateTime::UNIX_EPOCH),
227    /// );
228    /// assert_eq!(
229    ///     UtcDateTime::from_unix_timestamp_nanos(1_546_300_800_000_000_000),
230    ///     Ok(utc_datetime!(2019-01-01 0:00)),
231    /// );
232    /// ```
233    pub const fn from_unix_timestamp_nanos(timestamp: i128) -> Result<Self, error::ComponentRange> {
234        let datetime = const_try!(Self::from_unix_timestamp(div_floor!(
235            timestamp,
236            Nanosecond::per(Second) as i128
237        ) as i64));
238
239        Ok(Self::new(
240            datetime.date(),
241            // Safety: `nanosecond` is in range due to `rem_euclid`.
242            unsafe {
243                Time::__from_hms_nanos_unchecked(
244                    datetime.hour(),
245                    datetime.minute(),
246                    datetime.second(),
247                    timestamp.rem_euclid(Nanosecond::per(Second) as i128) as u32,
248                )
249            },
250        ))
251    }
252
253    /// Convert the `UtcDateTime` from UTC to the provided [`UtcOffset`], returning an
254    /// [`OffsetDateTime`].
255    ///
256    /// ```rust
257    /// # use time_macros::{utc_datetime, offset};
258    /// assert_eq!(
259    ///     utc_datetime!(2000-01-01 0:00)
260    ///         .to_offset(offset!(-1))
261    ///         .year(),
262    ///     1999,
263    /// );
264    ///
265    /// // Construct midnight on new year's, UTC.
266    /// let utc = utc_datetime!(2000-01-01 0:00);
267    /// let new_york = utc.to_offset(offset!(-5));
268    /// let los_angeles = utc.to_offset(offset!(-8));
269    /// assert_eq!(utc.hour(), 0);
270    /// assert_eq!(new_york.hour(), 19);
271    /// assert_eq!(los_angeles.hour(), 16);
272    /// ```
273    ///
274    /// # Panics
275    ///
276    /// This method panics if the local date-time in the new offset is outside the supported range.
277    pub const fn to_offset(self, offset: UtcOffset) -> OffsetDateTime {
278        expect_opt!(
279            self.checked_to_offset(offset),
280            "local datetime out of valid range"
281        )
282    }
283
284    /// Convert the `UtcDateTime` from UTC to the provided [`UtcOffset`], returning an
285    /// [`OffsetDateTime`]. `None` is returned if the date-time in the resulting offset is
286    /// invalid.
287    ///
288    /// ```rust
289    /// # use time::UtcDateTime;
290    /// # use time_macros::{utc_datetime, offset};
291    /// assert_eq!(
292    ///     utc_datetime!(2000-01-01 0:00)
293    ///         .checked_to_offset(offset!(-1))
294    ///         .unwrap()
295    ///         .year(),
296    ///     1999,
297    /// );
298    /// assert_eq!(
299    ///     UtcDateTime::MAX.checked_to_offset(offset!(+1)),
300    ///     None,
301    /// );
302    /// ```
303    pub const fn checked_to_offset(self, offset: UtcOffset) -> Option<OffsetDateTime> {
304        // Fast path for when no conversion is necessary.
305        if offset.is_utc() {
306            return Some(self.inner.assume_utc());
307        }
308
309        let (year, ordinal, time) = self.to_offset_raw(offset);
310
311        if year > MAX_YEAR || year < MIN_YEAR {
312            return None;
313        }
314
315        Some(OffsetDateTime::new_in_offset(
316            // Safety: `ordinal` is not zero.
317            unsafe { Date::__from_ordinal_date_unchecked(year, ordinal) },
318            time,
319            offset,
320        ))
321    }
322
323    /// Equivalent to `.to_offset(UtcOffset::UTC)`, but returning the year, ordinal, and time. This
324    /// avoids constructing an invalid [`Date`] if the new value is out of range.
325    pub(crate) const fn to_offset_raw(self, offset: UtcOffset) -> (i32, u16, Time) {
326        let mut second = self.second() as i16 + offset.seconds_past_minute() as i16;
327        let mut minute = self.minute() as i16 + offset.minutes_past_hour() as i16;
328        let mut hour = self.hour() as i8 + offset.whole_hours();
329        let (mut year, ordinal) = self.to_ordinal_date();
330        let mut ordinal = ordinal as i16;
331
332        cascade!(second in 0..Second::per(Minute) as i16 => minute);
333        cascade!(minute in 0..Minute::per(Hour) as i16 => hour);
334        cascade!(hour in 0..Hour::per(Day) as i8 => ordinal);
335        cascade!(ordinal => year);
336
337        debug_assert!(ordinal > 0);
338        debug_assert!(ordinal <= util::days_in_year(year) as i16);
339
340        (
341            year,
342            ordinal as u16,
343            // Safety: The cascades above ensure the values are in range.
344            unsafe {
345                Time::__from_hms_nanos_unchecked(
346                    hour as u8,
347                    minute as u8,
348                    second as u8,
349                    self.nanosecond(),
350                )
351            },
352        )
353    }
354
355    /// Get the [Unix timestamp](https://en.wikipedia.org/wiki/Unix_time).
356    ///
357    /// ```rust
358    /// # use time_macros::utc_datetime;
359    /// assert_eq!(utc_datetime!(1970-01-01 0:00).unix_timestamp(), 0);
360    /// assert_eq!(utc_datetime!(1970-01-01 1:00).unix_timestamp(), 3_600);
361    /// ```
362    pub const fn unix_timestamp(self) -> i64 {
363        let days =
364            (self.to_julian_day() as i64 - UNIX_EPOCH_JULIAN_DAY as i64) * Second::per(Day) as i64;
365        let hours = self.hour() as i64 * Second::per(Hour) as i64;
366        let minutes = self.minute() as i64 * Second::per(Minute) as i64;
367        let seconds = self.second() as i64;
368        days + hours + minutes + seconds
369    }
370
371    /// Get the Unix timestamp in nanoseconds.
372    ///
373    /// ```rust
374    /// use time_macros::utc_datetime;
375    /// assert_eq!(utc_datetime!(1970-01-01 0:00).unix_timestamp_nanos(), 0);
376    /// assert_eq!(
377    ///     utc_datetime!(1970-01-01 1:00).unix_timestamp_nanos(),
378    ///     3_600_000_000_000,
379    /// );
380    /// ```
381    pub const fn unix_timestamp_nanos(self) -> i128 {
382        self.unix_timestamp() as i128 * Nanosecond::per(Second) as i128 + self.nanosecond() as i128
383    }
384
385    /// Get the [`Date`] component of the `UtcDateTime`.
386    ///
387    /// ```rust
388    /// # use time_macros::{date, utc_datetime};
389    /// assert_eq!(utc_datetime!(2019-01-01 0:00).date(), date!(2019-01-01));
390    /// ```
391    pub const fn date(self) -> Date {
392        self.inner.date()
393    }
394
395    /// Get the [`Time`] component of the `UtcDateTime`.
396    ///
397    /// ```rust
398    /// # use time_macros::{utc_datetime, time};
399    /// assert_eq!(utc_datetime!(2019-01-01 0:00).time(), time!(0:00));
400    /// ```
401    pub const fn time(self) -> Time {
402        self.inner.time()
403    }
404
405    /// Get the year of the date.
406    ///
407    /// ```rust
408    /// # use time_macros::utc_datetime;
409    /// assert_eq!(utc_datetime!(2019-01-01 0:00).year(), 2019);
410    /// assert_eq!(utc_datetime!(2019-12-31 0:00).year(), 2019);
411    /// assert_eq!(utc_datetime!(2020-01-01 0:00).year(), 2020);
412    /// ```
413    pub const fn year(self) -> i32 {
414        self.date().year()
415    }
416
417    /// Get the month of the date.
418    ///
419    /// ```rust
420    /// # use time::Month;
421    /// # use time_macros::utc_datetime;
422    /// assert_eq!(utc_datetime!(2019-01-01 0:00).month(), Month::January);
423    /// assert_eq!(utc_datetime!(2019-12-31 0:00).month(), Month::December);
424    /// ```
425    pub const fn month(self) -> Month {
426        self.date().month()
427    }
428
429    /// Get the day of the date.
430    ///
431    /// The returned value will always be in the range `1..=31`.
432    ///
433    /// ```rust
434    /// # use time_macros::utc_datetime;
435    /// assert_eq!(utc_datetime!(2019-01-01 0:00).day(), 1);
436    /// assert_eq!(utc_datetime!(2019-12-31 0:00).day(), 31);
437    /// ```
438    pub const fn day(self) -> u8 {
439        self.date().day()
440    }
441
442    /// Get the day of the year.
443    ///
444    /// The returned value will always be in the range `1..=366` (`1..=365` for common years).
445    ///
446    /// ```rust
447    /// # use time_macros::utc_datetime;
448    /// assert_eq!(utc_datetime!(2019-01-01 0:00).ordinal(), 1);
449    /// assert_eq!(utc_datetime!(2019-12-31 0:00).ordinal(), 365);
450    /// ```
451    pub const fn ordinal(self) -> u16 {
452        self.date().ordinal()
453    }
454
455    /// Get the ISO week number.
456    ///
457    /// The returned value will always be in the range `1..=53`.
458    ///
459    /// ```rust
460    /// # use time_macros::utc_datetime;
461    /// assert_eq!(utc_datetime!(2019-01-01 0:00).iso_week(), 1);
462    /// assert_eq!(utc_datetime!(2019-10-04 0:00).iso_week(), 40);
463    /// assert_eq!(utc_datetime!(2020-01-01 0:00).iso_week(), 1);
464    /// assert_eq!(utc_datetime!(2020-12-31 0:00).iso_week(), 53);
465    /// assert_eq!(utc_datetime!(2021-01-01 0:00).iso_week(), 53);
466    /// ```
467    pub const fn iso_week(self) -> u8 {
468        self.date().iso_week()
469    }
470
471    /// Get the week number where week 1 begins on the first Sunday.
472    ///
473    /// The returned value will always be in the range `0..=53`.
474    ///
475    /// ```rust
476    /// # use time_macros::utc_datetime;
477    /// assert_eq!(utc_datetime!(2019-01-01 0:00).sunday_based_week(), 0);
478    /// assert_eq!(utc_datetime!(2020-01-01 0:00).sunday_based_week(), 0);
479    /// assert_eq!(utc_datetime!(2020-12-31 0:00).sunday_based_week(), 52);
480    /// assert_eq!(utc_datetime!(2021-01-01 0:00).sunday_based_week(), 0);
481    /// ```
482    pub const fn sunday_based_week(self) -> u8 {
483        self.date().sunday_based_week()
484    }
485
486    /// Get the week number where week 1 begins on the first Monday.
487    ///
488    /// The returned value will always be in the range `0..=53`.
489    ///
490    /// ```rust
491    /// # use time_macros::utc_datetime;
492    /// assert_eq!(utc_datetime!(2019-01-01 0:00).monday_based_week(), 0);
493    /// assert_eq!(utc_datetime!(2020-01-01 0:00).monday_based_week(), 0);
494    /// assert_eq!(utc_datetime!(2020-12-31 0:00).monday_based_week(), 52);
495    /// assert_eq!(utc_datetime!(2021-01-01 0:00).monday_based_week(), 0);
496    /// ```
497    pub const fn monday_based_week(self) -> u8 {
498        self.date().monday_based_week()
499    }
500
501    /// Get the year, month, and day.
502    ///
503    /// ```rust
504    /// # use time::Month;
505    /// # use time_macros::utc_datetime;
506    /// assert_eq!(
507    ///     utc_datetime!(2019-01-01 0:00).to_calendar_date(),
508    ///     (2019, Month::January, 1)
509    /// );
510    /// ```
511    pub const fn to_calendar_date(self) -> (i32, Month, u8) {
512        self.date().to_calendar_date()
513    }
514
515    /// Get the year and ordinal day number.
516    ///
517    /// ```rust
518    /// # use time_macros::utc_datetime;
519    /// assert_eq!(utc_datetime!(2019-01-01 0:00).to_ordinal_date(), (2019, 1));
520    /// ```
521    pub const fn to_ordinal_date(self) -> (i32, u16) {
522        self.date().to_ordinal_date()
523    }
524
525    /// Get the ISO 8601 year, week number, and weekday.
526    ///
527    /// ```rust
528    /// # use time::Weekday::*;
529    /// # use time_macros::utc_datetime;
530    /// assert_eq!(
531    ///     utc_datetime!(2019-01-01 0:00).to_iso_week_date(),
532    ///     (2019, 1, Tuesday)
533    /// );
534    /// assert_eq!(
535    ///     utc_datetime!(2019-10-04 0:00).to_iso_week_date(),
536    ///     (2019, 40, Friday)
537    /// );
538    /// assert_eq!(
539    ///     utc_datetime!(2020-01-01 0:00).to_iso_week_date(),
540    ///     (2020, 1, Wednesday)
541    /// );
542    /// assert_eq!(
543    ///     utc_datetime!(2020-12-31 0:00).to_iso_week_date(),
544    ///     (2020, 53, Thursday)
545    /// );
546    /// assert_eq!(
547    ///     utc_datetime!(2021-01-01 0:00).to_iso_week_date(),
548    ///     (2020, 53, Friday)
549    /// );
550    /// ```
551    pub const fn to_iso_week_date(self) -> (i32, u8, Weekday) {
552        self.date().to_iso_week_date()
553    }
554
555    /// Get the weekday.
556    ///
557    /// ```rust
558    /// # use time::Weekday::*;
559    /// # use time_macros::utc_datetime;
560    /// assert_eq!(utc_datetime!(2019-01-01 0:00).weekday(), Tuesday);
561    /// assert_eq!(utc_datetime!(2019-02-01 0:00).weekday(), Friday);
562    /// assert_eq!(utc_datetime!(2019-03-01 0:00).weekday(), Friday);
563    /// assert_eq!(utc_datetime!(2019-04-01 0:00).weekday(), Monday);
564    /// assert_eq!(utc_datetime!(2019-05-01 0:00).weekday(), Wednesday);
565    /// assert_eq!(utc_datetime!(2019-06-01 0:00).weekday(), Saturday);
566    /// assert_eq!(utc_datetime!(2019-07-01 0:00).weekday(), Monday);
567    /// assert_eq!(utc_datetime!(2019-08-01 0:00).weekday(), Thursday);
568    /// assert_eq!(utc_datetime!(2019-09-01 0:00).weekday(), Sunday);
569    /// assert_eq!(utc_datetime!(2019-10-01 0:00).weekday(), Tuesday);
570    /// assert_eq!(utc_datetime!(2019-11-01 0:00).weekday(), Friday);
571    /// assert_eq!(utc_datetime!(2019-12-01 0:00).weekday(), Sunday);
572    /// ```
573    pub const fn weekday(self) -> Weekday {
574        self.date().weekday()
575    }
576
577    /// Get the Julian day for the date. The time is not taken into account for this calculation.
578    ///
579    /// The algorithm to perform this conversion is derived from one provided by Peter Baum; it is
580    /// freely available [here](https://www.researchgate.net/publication/316558298_Date_Algorithms).
581    ///
582    /// ```rust
583    /// # use time_macros::utc_datetime;
584    /// assert_eq!(utc_datetime!(-4713-11-24 0:00).to_julian_day(), 0);
585    /// assert_eq!(utc_datetime!(2000-01-01 0:00).to_julian_day(), 2_451_545);
586    /// assert_eq!(utc_datetime!(2019-01-01 0:00).to_julian_day(), 2_458_485);
587    /// assert_eq!(utc_datetime!(2019-12-31 0:00).to_julian_day(), 2_458_849);
588    /// ```
589    pub const fn to_julian_day(self) -> i32 {
590        self.date().to_julian_day()
591    }
592
593    /// Get the clock hour, minute, and second.
594    ///
595    /// ```rust
596    /// # use time_macros::utc_datetime;
597    /// assert_eq!(utc_datetime!(2020-01-01 0:00:00).as_hms(), (0, 0, 0));
598    /// assert_eq!(utc_datetime!(2020-01-01 23:59:59).as_hms(), (23, 59, 59));
599    /// ```
600    pub const fn as_hms(self) -> (u8, u8, u8) {
601        self.time().as_hms()
602    }
603
604    /// Get the clock hour, minute, second, and millisecond.
605    ///
606    /// ```rust
607    /// # use time_macros::utc_datetime;
608    /// assert_eq!(utc_datetime!(2020-01-01 0:00:00).as_hms_milli(), (0, 0, 0, 0));
609    /// assert_eq!(
610    ///     utc_datetime!(2020-01-01 23:59:59.999).as_hms_milli(),
611    ///     (23, 59, 59, 999)
612    /// );
613    /// ```
614    pub const fn as_hms_milli(self) -> (u8, u8, u8, u16) {
615        self.time().as_hms_milli()
616    }
617
618    /// Get the clock hour, minute, second, and microsecond.
619    ///
620    /// ```rust
621    /// # use time_macros::utc_datetime;
622    /// assert_eq!(utc_datetime!(2020-01-01 0:00:00).as_hms_micro(), (0, 0, 0, 0));
623    /// assert_eq!(
624    ///     utc_datetime!(2020-01-01 23:59:59.999_999).as_hms_micro(),
625    ///     (23, 59, 59, 999_999)
626    /// );
627    /// ```
628    pub const fn as_hms_micro(self) -> (u8, u8, u8, u32) {
629        self.time().as_hms_micro()
630    }
631
632    /// Get the clock hour, minute, second, and nanosecond.
633    ///
634    /// ```rust
635    /// # use time_macros::utc_datetime;
636    /// assert_eq!(utc_datetime!(2020-01-01 0:00:00).as_hms_nano(), (0, 0, 0, 0));
637    /// assert_eq!(
638    ///     utc_datetime!(2020-01-01 23:59:59.999_999_999).as_hms_nano(),
639    ///     (23, 59, 59, 999_999_999)
640    /// );
641    /// ```
642    pub const fn as_hms_nano(self) -> (u8, u8, u8, u32) {
643        self.time().as_hms_nano()
644    }
645
646    /// Get the clock hour.
647    ///
648    /// The returned value will always be in the range `0..24`.
649    ///
650    /// ```rust
651    /// # use time_macros::utc_datetime;
652    /// assert_eq!(utc_datetime!(2019-01-01 0:00).hour(), 0);
653    /// assert_eq!(utc_datetime!(2019-01-01 23:59:59).hour(), 23);
654    /// ```
655    pub const fn hour(self) -> u8 {
656        self.time().hour()
657    }
658
659    /// Get the minute within the hour.
660    ///
661    /// The returned value will always be in the range `0..60`.
662    ///
663    /// ```rust
664    /// # use time_macros::utc_datetime;
665    /// assert_eq!(utc_datetime!(2019-01-01 0:00).minute(), 0);
666    /// assert_eq!(utc_datetime!(2019-01-01 23:59:59).minute(), 59);
667    /// ```
668    pub const fn minute(self) -> u8 {
669        self.time().minute()
670    }
671
672    /// Get the second within the minute.
673    ///
674    /// The returned value will always be in the range `0..60`.
675    ///
676    /// ```rust
677    /// # use time_macros::utc_datetime;
678    /// assert_eq!(utc_datetime!(2019-01-01 0:00).second(), 0);
679    /// assert_eq!(utc_datetime!(2019-01-01 23:59:59).second(), 59);
680    /// ```
681    pub const fn second(self) -> u8 {
682        self.time().second()
683    }
684
685    /// Get the milliseconds within the second.
686    ///
687    /// The returned value will always be in the range `0..1_000`.
688    ///
689    /// ```rust
690    /// # use time_macros::utc_datetime;
691    /// assert_eq!(utc_datetime!(2019-01-01 0:00).millisecond(), 0);
692    /// assert_eq!(utc_datetime!(2019-01-01 23:59:59.999).millisecond(), 999);
693    /// ```
694    pub const fn millisecond(self) -> u16 {
695        self.time().millisecond()
696    }
697
698    /// Get the microseconds within the second.
699    ///
700    /// The returned value will always be in the range `0..1_000_000`.
701    ///
702    /// ```rust
703    /// # use time_macros::utc_datetime;
704    /// assert_eq!(utc_datetime!(2019-01-01 0:00).microsecond(), 0);
705    /// assert_eq!(
706    ///     utc_datetime!(2019-01-01 23:59:59.999_999).microsecond(),
707    ///     999_999
708    /// );
709    /// ```
710    pub const fn microsecond(self) -> u32 {
711        self.time().microsecond()
712    }
713
714    /// Get the nanoseconds within the second.
715    ///
716    /// The returned value will always be in the range `0..1_000_000_000`.
717    ///
718    /// ```rust
719    /// # use time_macros::utc_datetime;
720    /// assert_eq!(utc_datetime!(2019-01-01 0:00).nanosecond(), 0);
721    /// assert_eq!(
722    ///     utc_datetime!(2019-01-01 23:59:59.999_999_999).nanosecond(),
723    ///     999_999_999,
724    /// );
725    /// ```
726    pub const fn nanosecond(self) -> u32 {
727        self.time().nanosecond()
728    }
729
730    /// Computes `self + duration`, returning `None` if an overflow occurred.
731    ///
732    /// ```rust
733    /// # use time::{UtcDateTime, ext::NumericalDuration};
734    /// # use time_macros::utc_datetime;
735    /// assert_eq!(UtcDateTime::MIN.checked_add((-2).days()), None);
736    /// assert_eq!(UtcDateTime::MAX.checked_add(1.days()), None);
737    /// assert_eq!(
738    ///     utc_datetime!(2019 - 11 - 25 15:30).checked_add(27.hours()),
739    ///     Some(utc_datetime!(2019 - 11 - 26 18:30))
740    /// );
741    /// ```
742    pub const fn checked_add(self, duration: Duration) -> Option<Self> {
743        Some(Self::from_primitive(const_try_opt!(self
744            .inner
745            .checked_add(duration))))
746    }
747
748    /// Computes `self - duration`, returning `None` if an overflow occurred.
749    ///
750    /// ```rust
751    /// # use time::{UtcDateTime, ext::NumericalDuration};
752    /// # use time_macros::utc_datetime;
753    /// assert_eq!(UtcDateTime::MIN.checked_sub(2.days()), None);
754    /// assert_eq!(UtcDateTime::MAX.checked_sub((-1).days()), None);
755    /// assert_eq!(
756    ///     utc_datetime!(2019 - 11 - 25 15:30).checked_sub(27.hours()),
757    ///     Some(utc_datetime!(2019 - 11 - 24 12:30))
758    /// );
759    /// ```
760    pub const fn checked_sub(self, duration: Duration) -> Option<Self> {
761        Some(Self::from_primitive(const_try_opt!(self
762            .inner
763            .checked_sub(duration))))
764    }
765
766    /// Computes `self + duration`, saturating value on overflow.
767    ///
768    /// ```rust
769    /// # use time::{UtcDateTime, ext::NumericalDuration};
770    /// # use time_macros::utc_datetime;
771    /// assert_eq!(
772    ///     UtcDateTime::MIN.saturating_add((-2).days()),
773    ///     UtcDateTime::MIN
774    /// );
775    /// assert_eq!(
776    ///     UtcDateTime::MAX.saturating_add(2.days()),
777    ///     UtcDateTime::MAX
778    /// );
779    /// assert_eq!(
780    ///     utc_datetime!(2019 - 11 - 25 15:30).saturating_add(27.hours()),
781    ///     utc_datetime!(2019 - 11 - 26 18:30)
782    /// );
783    /// ```
784    pub const fn saturating_add(self, duration: Duration) -> Self {
785        Self::from_primitive(self.inner.saturating_add(duration))
786    }
787
788    /// Computes `self - duration`, saturating value on overflow.
789    ///
790    /// ```rust
791    /// # use time::{UtcDateTime, ext::NumericalDuration};
792    /// # use time_macros::utc_datetime;
793    /// assert_eq!(
794    ///     UtcDateTime::MIN.saturating_sub(2.days()),
795    ///     UtcDateTime::MIN
796    /// );
797    /// assert_eq!(
798    ///     UtcDateTime::MAX.saturating_sub((-2).days()),
799    ///     UtcDateTime::MAX
800    /// );
801    /// assert_eq!(
802    ///     utc_datetime!(2019 - 11 - 25 15:30).saturating_sub(27.hours()),
803    ///     utc_datetime!(2019 - 11 - 24 12:30)
804    /// );
805    /// ```
806    pub const fn saturating_sub(self, duration: Duration) -> Self {
807        Self::from_primitive(self.inner.saturating_sub(duration))
808    }
809}
810
811/// Methods that replace part of the `UtcDateTime`.
812impl UtcDateTime {
813    /// Replace the time, preserving the date.
814    ///
815    /// ```rust
816    /// # use time_macros::{utc_datetime, time};
817    /// assert_eq!(
818    ///     utc_datetime!(2020-01-01 17:00).replace_time(time!(5:00)),
819    ///     utc_datetime!(2020-01-01 5:00)
820    /// );
821    /// ```
822    #[must_use = "This method does not mutate the original `UtcDateTime`."]
823    pub const fn replace_time(self, time: Time) -> Self {
824        Self::from_primitive(self.inner.replace_time(time))
825    }
826
827    /// Replace the date, preserving the time.
828    ///
829    /// ```rust
830    /// # use time_macros::{utc_datetime, date};
831    /// assert_eq!(
832    ///     utc_datetime!(2020-01-01 12:00).replace_date(date!(2020-01-30)),
833    ///     utc_datetime!(2020-01-30 12:00)
834    /// );
835    /// ```
836    #[must_use = "This method does not mutate the original `UtcDateTime`."]
837    pub const fn replace_date(self, date: Date) -> Self {
838        Self::from_primitive(self.inner.replace_date(date))
839    }
840
841    /// Replace the year. The month and day will be unchanged.
842    ///
843    /// ```rust
844    /// # use time_macros::utc_datetime;
845    /// assert_eq!(
846    ///     utc_datetime!(2022 - 02 - 18 12:00).replace_year(2019),
847    ///     Ok(utc_datetime!(2019 - 02 - 18 12:00))
848    /// );
849    /// assert!(utc_datetime!(2022 - 02 - 18 12:00).replace_year(-1_000_000_000).is_err()); // -1_000_000_000 isn't a valid year
850    /// assert!(utc_datetime!(2022 - 02 - 18 12:00).replace_year(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid year
851    /// ```
852    #[must_use = "This method does not mutate the original `UtcDateTime`."]
853    pub const fn replace_year(self, year: i32) -> Result<Self, error::ComponentRange> {
854        Ok(Self::from_primitive(const_try!(self
855            .inner
856            .replace_year(year))))
857    }
858
859    /// Replace the month of the year.
860    ///
861    /// ```rust
862    /// # use time_macros::utc_datetime;
863    /// # use time::Month;
864    /// assert_eq!(
865    ///     utc_datetime!(2022 - 02 - 18 12:00).replace_month(Month::January),
866    ///     Ok(utc_datetime!(2022 - 01 - 18 12:00))
867    /// );
868    /// assert!(utc_datetime!(2022 - 01 - 30 12:00).replace_month(Month::February).is_err()); // 30 isn't a valid day in February
869    /// ```
870    #[must_use = "This method does not mutate the original `UtcDateTime`."]
871    pub const fn replace_month(self, month: Month) -> Result<Self, error::ComponentRange> {
872        Ok(Self::from_primitive(const_try!(self
873            .inner
874            .replace_month(month))))
875    }
876
877    /// Replace the day of the month.
878    ///
879    /// ```rust
880    /// # use time_macros::utc_datetime;
881    /// assert_eq!(
882    ///     utc_datetime!(2022 - 02 - 18 12:00).replace_day(1),
883    ///     Ok(utc_datetime!(2022 - 02 - 01 12:00))
884    /// );
885    /// assert!(utc_datetime!(2022 - 02 - 18 12:00).replace_day(0).is_err()); // 00 isn't a valid day
886    /// assert!(utc_datetime!(2022 - 02 - 18 12:00).replace_day(30).is_err()); // 30 isn't a valid day in February
887    /// ```
888    #[must_use = "This method does not mutate the original `UtcDateTime`."]
889    pub const fn replace_day(self, day: u8) -> Result<Self, error::ComponentRange> {
890        Ok(Self::from_primitive(const_try!(self
891            .inner
892            .replace_day(day))))
893    }
894
895    /// Replace the day of the year.
896    ///
897    /// ```rust
898    /// # use time_macros::utc_datetime;
899    /// assert_eq!(utc_datetime!(2022-049 12:00).replace_ordinal(1), Ok(utc_datetime!(2022-001 12:00)));
900    /// assert!(utc_datetime!(2022-049 12:00).replace_ordinal(0).is_err()); // 0 isn't a valid ordinal
901    /// assert!(utc_datetime!(2022-049 12:00).replace_ordinal(366).is_err()); // 2022 isn't a leap year
902    /// ```
903    #[must_use = "This method does not mutate the original `UtcDateTime`."]
904    pub const fn replace_ordinal(self, ordinal: u16) -> Result<Self, error::ComponentRange> {
905        Ok(Self::from_primitive(const_try!(self
906            .inner
907            .replace_ordinal(ordinal))))
908    }
909
910    /// Replace the clock hour.
911    ///
912    /// ```rust
913    /// # use time_macros::utc_datetime;
914    /// assert_eq!(
915    ///     utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_hour(7),
916    ///     Ok(utc_datetime!(2022 - 02 - 18 07:02:03.004_005_006))
917    /// );
918    /// assert!(utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_hour(24).is_err()); // 24 isn't a valid hour
919    /// ```
920    #[must_use = "This method does not mutate the original `UtcDateTime`."]
921    pub const fn replace_hour(self, hour: u8) -> Result<Self, error::ComponentRange> {
922        Ok(Self::from_primitive(const_try!(self
923            .inner
924            .replace_hour(hour))))
925    }
926
927    /// Replace the minutes within the hour.
928    ///
929    /// ```rust
930    /// # use time_macros::utc_datetime;
931    /// assert_eq!(
932    ///     utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_minute(7),
933    ///     Ok(utc_datetime!(2022 - 02 - 18 01:07:03.004_005_006))
934    /// );
935    /// assert!(utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_minute(60).is_err()); // 60 isn't a valid minute
936    /// ```
937    #[must_use = "This method does not mutate the original `UtcDateTime`."]
938    pub const fn replace_minute(
939        self,
940        sunday_based_week: u8,
941    ) -> Result<Self, error::ComponentRange> {
942        Ok(Self::from_primitive(const_try!(self
943            .inner
944            .replace_minute(sunday_based_week))))
945    }
946
947    /// Replace the seconds within the minute.
948    ///
949    /// ```rust
950    /// # use time_macros::utc_datetime;
951    /// assert_eq!(
952    ///     utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_second(7),
953    ///     Ok(utc_datetime!(2022 - 02 - 18 01:02:07.004_005_006))
954    /// );
955    /// assert!(utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_second(60).is_err()); // 60 isn't a valid second
956    /// ```
957    #[must_use = "This method does not mutate the original `UtcDateTime`."]
958    pub const fn replace_second(
959        self,
960        monday_based_week: u8,
961    ) -> Result<Self, error::ComponentRange> {
962        Ok(Self::from_primitive(const_try!(self
963            .inner
964            .replace_second(monday_based_week))))
965    }
966
967    /// Replace the milliseconds within the second.
968    ///
969    /// ```rust
970    /// # use time_macros::utc_datetime;
971    /// assert_eq!(
972    ///     utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_millisecond(7),
973    ///     Ok(utc_datetime!(2022 - 02 - 18 01:02:03.007))
974    /// );
975    /// assert!(utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_millisecond(1_000).is_err()); // 1_000 isn't a valid millisecond
976    /// ```
977    #[must_use = "This method does not mutate the original `UtcDateTime`."]
978    pub const fn replace_millisecond(
979        self,
980        millisecond: u16,
981    ) -> Result<Self, error::ComponentRange> {
982        Ok(Self::from_primitive(const_try!(self
983            .inner
984            .replace_millisecond(millisecond))))
985    }
986
987    /// Replace the microseconds within the second.
988    ///
989    /// ```rust
990    /// # use time_macros::utc_datetime;
991    /// assert_eq!(
992    ///     utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_microsecond(7_008),
993    ///     Ok(utc_datetime!(2022 - 02 - 18 01:02:03.007_008))
994    /// );
995    /// assert!(utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_microsecond(1_000_000).is_err()); // 1_000_000 isn't a valid microsecond
996    /// ```
997    #[must_use = "This method does not mutate the original `UtcDateTime`."]
998    pub const fn replace_microsecond(
999        self,
1000        microsecond: u32,
1001    ) -> Result<Self, error::ComponentRange> {
1002        Ok(Self::from_primitive(const_try!(self
1003            .inner
1004            .replace_microsecond(microsecond))))
1005    }
1006
1007    /// Replace the nanoseconds within the second.
1008    ///
1009    /// ```rust
1010    /// # use time_macros::utc_datetime;
1011    /// assert_eq!(
1012    ///     utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_nanosecond(7_008_009),
1013    ///     Ok(utc_datetime!(2022 - 02 - 18 01:02:03.007_008_009))
1014    /// );
1015    /// assert!(utc_datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_nanosecond(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid nanosecond
1016    /// ```
1017    #[must_use = "This method does not mutate the original `UtcDateTime`."]
1018    pub const fn replace_nanosecond(self, nanosecond: u32) -> Result<Self, error::ComponentRange> {
1019        Ok(Self::from_primitive(const_try!(self
1020            .inner
1021            .replace_nanosecond(nanosecond))))
1022    }
1023}
1024
1025#[cfg(feature = "formatting")]
1026impl UtcDateTime {
1027    /// Format the `UtcDateTime` using the provided [format
1028    /// description](crate::format_description).
1029    pub fn format_into(
1030        self,
1031        output: &mut (impl io::Write + ?Sized),
1032        format: &(impl Formattable + ?Sized),
1033    ) -> Result<usize, error::Format> {
1034        format.format_into(
1035            output,
1036            Some(self.date()),
1037            Some(self.time()),
1038            Some(UtcOffset::UTC),
1039        )
1040    }
1041
1042    /// Format the `UtcDateTime` using the provided [format
1043    /// description](crate::format_description).
1044    ///
1045    /// ```rust
1046    /// # use time::format_description;
1047    /// # use time_macros::utc_datetime;
1048    /// let format = format_description::parse(
1049    ///     "[year]-[month]-[day] [hour]:[minute]:[second] [offset_hour \
1050    ///          sign:mandatory]:[offset_minute]:[offset_second]",
1051    /// )?;
1052    /// assert_eq!(
1053    ///     utc_datetime!(2020-01-02 03:04:05).format(&format)?,
1054    ///     "2020-01-02 03:04:05 +00:00:00"
1055    /// );
1056    /// # Ok::<_, time::Error>(())
1057    /// ```
1058    pub fn format(self, format: &(impl Formattable + ?Sized)) -> Result<String, error::Format> {
1059        format.format(Some(self.date()), Some(self.time()), Some(UtcOffset::UTC))
1060    }
1061}
1062
1063#[cfg(feature = "parsing")]
1064impl UtcDateTime {
1065    /// Parse an `UtcDateTime` from the input using the provided [format
1066    /// description](crate::format_description). A [`UtcOffset`] is permitted, but not required to
1067    /// be present. If present, the value will be converted to UTC.
1068    ///
1069    /// ```rust
1070    /// # use time::UtcDateTime;
1071    /// # use time_macros::{utc_datetime, format_description};
1072    /// let format = format_description!("[year]-[month]-[day] [hour]:[minute]:[second]");
1073    /// assert_eq!(
1074    ///     UtcDateTime::parse("2020-01-02 03:04:05", &format)?,
1075    ///     utc_datetime!(2020-01-02 03:04:05)
1076    /// );
1077    /// # Ok::<_, time::Error>(())
1078    /// ```
1079    pub fn parse(
1080        input: &str,
1081        description: &(impl Parsable + ?Sized),
1082    ) -> Result<Self, error::Parse> {
1083        description.parse_utc_date_time(input.as_bytes())
1084    }
1085
1086    /// A helper method to check if the `UtcDateTime` is a valid representation of a leap second.
1087    /// Leap seconds, when parsed, are represented as the preceding nanosecond. However, leap
1088    /// seconds can only occur as the last second of a month UTC.
1089    #[cfg(feature = "parsing")]
1090    pub(crate) const fn is_valid_leap_second_stand_in(self) -> bool {
1091        let dt = self.inner;
1092
1093        dt.hour() == 23
1094            && dt.minute() == 59
1095            && dt.second() == 59
1096            && dt.nanosecond() == 999_999_999
1097            && dt.day() == dt.month().length(dt.year())
1098    }
1099}
1100
1101impl SmartDisplay for UtcDateTime {
1102    type Metadata = ();
1103
1104    fn metadata(&self, _: FormatterOptions) -> Metadata<Self> {
1105        let width = smart_display::padded_width_of!(self.date(), " ", self.time(), " +00");
1106        Metadata::new(width, self, ())
1107    }
1108
1109    fn fmt_with_metadata(
1110        &self,
1111        f: &mut fmt::Formatter<'_>,
1112        metadata: Metadata<Self>,
1113    ) -> fmt::Result {
1114        f.pad_with_width(
1115            metadata.unpadded_width(),
1116            format_args!("{} {} +00", self.date(), self.time()),
1117        )
1118    }
1119}
1120
1121impl fmt::Display for UtcDateTime {
1122    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1123        SmartDisplay::fmt(self, f)
1124    }
1125}
1126
1127impl fmt::Debug for UtcDateTime {
1128    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1129        fmt::Display::fmt(self, f)
1130    }
1131}
1132
1133impl Add<Duration> for UtcDateTime {
1134    type Output = Self;
1135
1136    /// # Panics
1137    ///
1138    /// This may panic if an overflow occurs.
1139    fn add(self, duration: Duration) -> Self::Output {
1140        self.inner.add(duration).as_utc()
1141    }
1142}
1143
1144impl Add<StdDuration> for UtcDateTime {
1145    type Output = Self;
1146
1147    /// # Panics
1148    ///
1149    /// This may panic if an overflow occurs.
1150    fn add(self, duration: StdDuration) -> Self::Output {
1151        self.inner.add(duration).as_utc()
1152    }
1153}
1154
1155impl AddAssign<Duration> for UtcDateTime {
1156    /// # Panics
1157    ///
1158    /// This may panic if an overflow occurs.
1159    fn add_assign(&mut self, rhs: Duration) {
1160        self.inner.add_assign(rhs);
1161    }
1162}
1163
1164impl AddAssign<StdDuration> for UtcDateTime {
1165    /// # Panics
1166    ///
1167    /// This may panic if an overflow occurs.
1168    fn add_assign(&mut self, rhs: StdDuration) {
1169        self.inner.add_assign(rhs);
1170    }
1171}
1172
1173impl Sub<Duration> for UtcDateTime {
1174    type Output = Self;
1175
1176    /// # Panics
1177    ///
1178    /// This may panic if an overflow occurs.
1179    fn sub(self, rhs: Duration) -> Self::Output {
1180        self.checked_sub(rhs)
1181            .expect("resulting value is out of range")
1182    }
1183}
1184
1185impl Sub<StdDuration> for UtcDateTime {
1186    type Output = Self;
1187
1188    /// # Panics
1189    ///
1190    /// This may panic if an overflow occurs.
1191    fn sub(self, duration: StdDuration) -> Self::Output {
1192        Self::from_primitive(self.inner.sub(duration))
1193    }
1194}
1195
1196impl SubAssign<Duration> for UtcDateTime {
1197    /// # Panics
1198    ///
1199    /// This may panic if an overflow occurs.
1200    fn sub_assign(&mut self, rhs: Duration) {
1201        self.inner.sub_assign(rhs);
1202    }
1203}
1204
1205impl SubAssign<StdDuration> for UtcDateTime {
1206    /// # Panics
1207    ///
1208    /// This may panic if an overflow occurs.
1209    fn sub_assign(&mut self, rhs: StdDuration) {
1210        self.inner.sub_assign(rhs);
1211    }
1212}
1213
1214impl Sub for UtcDateTime {
1215    type Output = Duration;
1216
1217    /// # Panics
1218    ///
1219    /// This may panic if an overflow occurs.
1220    fn sub(self, rhs: Self) -> Self::Output {
1221        self.inner.sub(rhs.inner)
1222    }
1223}