Skip to main content

time/
plain_date_time.rs

1//! The [`PlainDateTime`] struct and its associated `impl`s.
2
3#[cfg(feature = "formatting")]
4use alloc::string::String;
5use core::cmp::Ordering;
6use core::fmt;
7use core::hash::{Hash, Hasher};
8use core::mem::MaybeUninit;
9use core::ops::{Add, AddAssign, Sub, SubAssign};
10use core::time::Duration as StdDuration;
11#[cfg(feature = "formatting")]
12use std::io;
13
14use powerfmt::smart_display::{self, FormatterOptions, Metadata, SmartDisplay};
15
16#[cfg(any(feature = "formatting", feature = "parsing"))]
17use crate::PrivateMethod;
18#[cfg(feature = "formatting")]
19use crate::formatting::Formattable;
20#[cfg(feature = "formatting")]
21use crate::internal_macros::try_likely_ok;
22use crate::internal_macros::{const_try, const_try_opt};
23use crate::num_fmt::str_from_raw_parts;
24#[cfg(feature = "parsing")]
25use crate::parsing::{Parsable, Parsed};
26use crate::{
27    Date, Month, OffsetDateTime, SignedDuration, Time, UtcDateTime, UtcOffset, Weekday, error, util,
28};
29
30/// Combined date and time.
31#[derive(Clone, Copy, Eq)]
32#[cfg_attr(not(docsrs), repr(C))]
33pub struct PlainDateTime {
34    // The order of this struct's fields matter! Do not reorder them.
35
36    // Little endian version
37    #[cfg(target_endian = "little")]
38    time: Time,
39    #[cfg(target_endian = "little")]
40    date: Date,
41
42    // Big endian version
43    #[cfg(target_endian = "big")]
44    date: Date,
45    #[cfg(target_endian = "big")]
46    time: Time,
47}
48
49impl Hash for PlainDateTime {
50    #[inline]
51    fn hash<H>(&self, state: &mut H)
52    where
53        H: Hasher,
54    {
55        self.as_i128().hash(state);
56    }
57}
58
59impl PartialEq for PlainDateTime {
60    #[inline]
61    fn eq(&self, other: &Self) -> bool {
62        self.as_i128().eq(&other.as_i128())
63    }
64}
65
66impl PartialOrd for PlainDateTime {
67    #[inline]
68    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
69        Some(self.cmp(other))
70    }
71}
72
73impl Ord for PlainDateTime {
74    #[inline]
75    fn cmp(&self, other: &Self) -> Ordering {
76        self.as_i128().cmp(&other.as_i128())
77    }
78}
79
80impl PlainDateTime {
81    /// Provide a representation of `PlainDateTime` as a `i128`. This value can be used for
82    /// equality, hashing, and ordering.
83    ///
84    /// **Note**: This value is explicitly signed, so do not cast this to or treat this as an
85    /// unsigned integer. Doing so will lead to incorrect results for values with differing
86    /// signs.
87    #[inline]
88    const fn as_i128(self) -> i128 {
89        let time = self.time.as_u64() as i128;
90        let date = self.date.as_i32() as i128;
91        (date << 64) | time
92    }
93
94    /// The smallest value that can be represented by `PlainDateTime`.
95    ///
96    /// Depending on `large-dates` feature flag, value of this constant may vary.
97    ///
98    /// 1. With `large-dates` disabled it is equal to `-9999-01-01 00:00:00.0`
99    /// 2. With `large-dates` enabled it is equal to `-999999-01-01 00:00:00.0`
100    ///
101    /// ```rust
102    /// # use time::PlainDateTime;
103    /// # use time_macros::datetime;
104    #[cfg_attr(
105        feature = "large-dates",
106        doc = "// Assuming `large-dates` feature is enabled."
107    )]
108    #[cfg_attr(
109        feature = "large-dates",
110        doc = "assert_eq!(PlainDateTime::MIN, datetime!(-999999-01-01 0:00));"
111    )]
112    #[cfg_attr(
113        not(feature = "large-dates"),
114        doc = "// Assuming `large-dates` feature is disabled."
115    )]
116    #[cfg_attr(
117        not(feature = "large-dates"),
118        doc = "assert_eq!(PlainDateTime::MIN, datetime!(-9999-01-01 0:00));"
119    )]
120    /// ```
121    pub const MIN: Self = Self {
122        date: Date::MIN,
123        time: Time::MIDNIGHT,
124    };
125
126    /// The largest value that can be represented by `PlainDateTime`.
127    ///
128    /// Depending on `large-dates` feature flag, value of this constant may vary.
129    ///
130    /// 1. With `large-dates` disabled it is equal to `9999-12-31 23:59:59.999_999_999`
131    /// 2. With `large-dates` enabled it is equal to `999999-12-31 23:59:59.999_999_999`
132    ///
133    /// ```rust
134    /// # use time::PlainDateTime;
135    /// # use time_macros::datetime;
136    #[cfg_attr(
137        feature = "large-dates",
138        doc = "// Assuming `large-dates` feature is enabled."
139    )]
140    #[cfg_attr(
141        feature = "large-dates",
142        doc = "assert_eq!(PlainDateTime::MAX, datetime!(+999999-12-31 23:59:59.999_999_999));"
143    )]
144    #[cfg_attr(
145        not(feature = "large-dates"),
146        doc = "// Assuming `large-dates` feature is disabled."
147    )]
148    #[cfg_attr(
149        not(feature = "large-dates"),
150        doc = "assert_eq!(PlainDateTime::MAX, datetime!(+9999-12-31 23:59:59.999_999_999));"
151    )]
152    /// ```
153    pub const MAX: Self = Self {
154        date: Date::MAX,
155        time: Time::MAX,
156    };
157
158    /// Create a new `PlainDateTime` from the provided [`Date`] and [`Time`].
159    ///
160    /// ```rust
161    /// # use time::PlainDateTime;
162    /// # use time_macros::{date, datetime, time};
163    /// assert_eq!(
164    ///     PlainDateTime::new(date!(2019-01-01), time!(0:00)),
165    ///     datetime!(2019-01-01 0:00),
166    /// );
167    /// ```
168    #[inline]
169    pub const fn new(date: Date, time: Time) -> Self {
170        Self { date, time }
171    }
172
173    /// Get the [`Date`] component of the `PlainDateTime`.
174    ///
175    /// ```rust
176    /// # use time_macros::{date, datetime};
177    /// assert_eq!(datetime!(2019-01-01 0:00).date(), date!(2019-01-01));
178    /// ```
179    #[inline]
180    pub const fn date(self) -> Date {
181        self.date
182    }
183
184    /// Get the [`Time`] component of the `PlainDateTime`.
185    ///
186    /// ```rust
187    /// # use time_macros::{datetime, time};
188    /// assert_eq!(datetime!(2019-01-01 0:00).time(), time!(0:00));
189    /// ```
190    #[inline]
191    pub const fn time(self) -> Time {
192        self.time
193    }
194
195    /// Get the year of the date.
196    ///
197    /// ```rust
198    /// # use time_macros::datetime;
199    /// assert_eq!(datetime!(2019-01-01 0:00).year(), 2019);
200    /// assert_eq!(datetime!(2019-12-31 0:00).year(), 2019);
201    /// assert_eq!(datetime!(2020-01-01 0:00).year(), 2020);
202    /// ```
203    #[inline]
204    pub const fn year(self) -> i32 {
205        self.date().year()
206    }
207
208    /// Get the month of the date.
209    ///
210    /// ```rust
211    /// # use time::Month;
212    /// # use time_macros::datetime;
213    /// assert_eq!(datetime!(2019-01-01 0:00).month(), Month::January);
214    /// assert_eq!(datetime!(2019-12-31 0:00).month(), Month::December);
215    /// ```
216    #[inline]
217    pub const fn month(self) -> Month {
218        self.date().month()
219    }
220
221    /// Get the day of the date.
222    ///
223    /// The returned value will always be in the range `1..=31`.
224    ///
225    /// ```rust
226    /// # use time_macros::datetime;
227    /// assert_eq!(datetime!(2019-01-01 0:00).day(), 1);
228    /// assert_eq!(datetime!(2019-12-31 0:00).day(), 31);
229    /// ```
230    #[inline]
231    pub const fn day(self) -> u8 {
232        self.date().day()
233    }
234
235    /// Get the day of the year.
236    ///
237    /// The returned value will always be in the range `1..=366` (`1..=365` for common years).
238    ///
239    /// ```rust
240    /// # use time_macros::datetime;
241    /// assert_eq!(datetime!(2019-01-01 0:00).ordinal(), 1);
242    /// assert_eq!(datetime!(2019-12-31 0:00).ordinal(), 365);
243    /// ```
244    #[inline]
245    pub const fn ordinal(self) -> u16 {
246        self.date().ordinal()
247    }
248
249    /// Get the ISO week number.
250    ///
251    /// The returned value will always be in the range `1..=53`.
252    ///
253    /// ```rust
254    /// # use time_macros::datetime;
255    /// assert_eq!(datetime!(2019-01-01 0:00).iso_week(), 1);
256    /// assert_eq!(datetime!(2019-10-04 0:00).iso_week(), 40);
257    /// assert_eq!(datetime!(2020-01-01 0:00).iso_week(), 1);
258    /// assert_eq!(datetime!(2020-12-31 0:00).iso_week(), 53);
259    /// assert_eq!(datetime!(2021-01-01 0:00).iso_week(), 53);
260    /// ```
261    #[inline]
262    pub const fn iso_week(self) -> u8 {
263        self.date().iso_week()
264    }
265
266    /// Get the week number where week 1 begins on the first Sunday.
267    ///
268    /// The returned value will always be in the range `0..=53`.
269    ///
270    /// ```rust
271    /// # use time_macros::datetime;
272    /// assert_eq!(datetime!(2019-01-01 0:00).sunday_based_week(), 0);
273    /// assert_eq!(datetime!(2020-01-01 0:00).sunday_based_week(), 0);
274    /// assert_eq!(datetime!(2020-12-31 0:00).sunday_based_week(), 52);
275    /// assert_eq!(datetime!(2021-01-01 0:00).sunday_based_week(), 0);
276    /// ```
277    #[inline]
278    pub const fn sunday_based_week(self) -> u8 {
279        self.date().sunday_based_week()
280    }
281
282    /// Get the week number where week 1 begins on the first Monday.
283    ///
284    /// The returned value will always be in the range `0..=53`.
285    ///
286    /// ```rust
287    /// # use time_macros::datetime;
288    /// assert_eq!(datetime!(2019-01-01 0:00).monday_based_week(), 0);
289    /// assert_eq!(datetime!(2020-01-01 0:00).monday_based_week(), 0);
290    /// assert_eq!(datetime!(2020-12-31 0:00).monday_based_week(), 52);
291    /// assert_eq!(datetime!(2021-01-01 0:00).monday_based_week(), 0);
292    /// ```
293    #[inline]
294    pub const fn monday_based_week(self) -> u8 {
295        self.date().monday_based_week()
296    }
297
298    /// Get the year, month, and day.
299    ///
300    /// ```rust
301    /// # use time::Month;
302    /// # use time_macros::datetime;
303    /// assert_eq!(
304    ///     datetime!(2019-01-01 0:00).to_calendar_date(),
305    ///     (2019, Month::January, 1)
306    /// );
307    /// ```
308    #[inline]
309    pub const fn to_calendar_date(self) -> (i32, Month, u8) {
310        self.date().to_calendar_date()
311    }
312
313    /// Get the year and ordinal day number.
314    ///
315    /// ```rust
316    /// # use time_macros::datetime;
317    /// assert_eq!(datetime!(2019-01-01 0:00).to_ordinal_date(), (2019, 1));
318    /// ```
319    #[inline]
320    pub const fn to_ordinal_date(self) -> (i32, u16) {
321        self.date().to_ordinal_date()
322    }
323
324    /// Get the ISO 8601 year, week number, and weekday.
325    ///
326    /// ```rust
327    /// # use time::Weekday::*;
328    /// # use time_macros::datetime;
329    /// assert_eq!(
330    ///     datetime!(2019-01-01 0:00).to_iso_week_date(),
331    ///     (2019, 1, Tuesday)
332    /// );
333    /// assert_eq!(
334    ///     datetime!(2019-10-04 0:00).to_iso_week_date(),
335    ///     (2019, 40, Friday)
336    /// );
337    /// assert_eq!(
338    ///     datetime!(2020-01-01 0:00).to_iso_week_date(),
339    ///     (2020, 1, Wednesday)
340    /// );
341    /// assert_eq!(
342    ///     datetime!(2020-12-31 0:00).to_iso_week_date(),
343    ///     (2020, 53, Thursday)
344    /// );
345    /// assert_eq!(
346    ///     datetime!(2021-01-01 0:00).to_iso_week_date(),
347    ///     (2020, 53, Friday)
348    /// );
349    /// ```
350    #[inline]
351    pub const fn to_iso_week_date(self) -> (i32, u8, Weekday) {
352        self.date().to_iso_week_date()
353    }
354
355    /// Get the weekday.
356    ///
357    /// ```rust
358    /// # use time::Weekday::*;
359    /// # use time_macros::datetime;
360    /// assert_eq!(datetime!(2019-01-01 0:00).weekday(), Tuesday);
361    /// assert_eq!(datetime!(2019-02-01 0:00).weekday(), Friday);
362    /// assert_eq!(datetime!(2019-03-01 0:00).weekday(), Friday);
363    /// assert_eq!(datetime!(2019-04-01 0:00).weekday(), Monday);
364    /// assert_eq!(datetime!(2019-05-01 0:00).weekday(), Wednesday);
365    /// assert_eq!(datetime!(2019-06-01 0:00).weekday(), Saturday);
366    /// assert_eq!(datetime!(2019-07-01 0:00).weekday(), Monday);
367    /// assert_eq!(datetime!(2019-08-01 0:00).weekday(), Thursday);
368    /// assert_eq!(datetime!(2019-09-01 0:00).weekday(), Sunday);
369    /// assert_eq!(datetime!(2019-10-01 0:00).weekday(), Tuesday);
370    /// assert_eq!(datetime!(2019-11-01 0:00).weekday(), Friday);
371    /// assert_eq!(datetime!(2019-12-01 0:00).weekday(), Sunday);
372    /// ```
373    #[inline]
374    pub const fn weekday(self) -> Weekday {
375        self.date().weekday()
376    }
377
378    /// Get the Julian day for the date. The time is not taken into account for this calculation.
379    ///
380    /// ```rust
381    /// # use time_macros::datetime;
382    /// assert_eq!(datetime!(-4713-11-24 0:00).to_julian_day(), 0);
383    /// assert_eq!(datetime!(2000-01-01 0:00).to_julian_day(), 2_451_545);
384    /// assert_eq!(datetime!(2019-01-01 0:00).to_julian_day(), 2_458_485);
385    /// assert_eq!(datetime!(2019-12-31 0:00).to_julian_day(), 2_458_849);
386    /// ```
387    #[inline]
388    pub const fn to_julian_day(self) -> i32 {
389        self.date().to_julian_day()
390    }
391
392    /// Get the clock hour, minute, and second.
393    ///
394    /// ```rust
395    /// # use time_macros::datetime;
396    /// assert_eq!(datetime!(2020-01-01 0:00:00).as_hms(), (0, 0, 0));
397    /// assert_eq!(datetime!(2020-01-01 23:59:59).as_hms(), (23, 59, 59));
398    /// ```
399    #[inline]
400    pub const fn as_hms(self) -> (u8, u8, u8) {
401        self.time().as_hms()
402    }
403
404    /// Get the clock hour, minute, second, and millisecond.
405    ///
406    /// ```rust
407    /// # use time_macros::datetime;
408    /// assert_eq!(datetime!(2020-01-01 0:00:00).as_hms_milli(), (0, 0, 0, 0));
409    /// assert_eq!(
410    ///     datetime!(2020-01-01 23:59:59.999).as_hms_milli(),
411    ///     (23, 59, 59, 999)
412    /// );
413    /// ```
414    #[inline]
415    pub const fn as_hms_milli(self) -> (u8, u8, u8, u16) {
416        self.time().as_hms_milli()
417    }
418
419    /// Get the clock hour, minute, second, and microsecond.
420    ///
421    /// ```rust
422    /// # use time_macros::datetime;
423    /// assert_eq!(datetime!(2020-01-01 0:00:00).as_hms_micro(), (0, 0, 0, 0));
424    /// assert_eq!(
425    ///     datetime!(2020-01-01 23:59:59.999_999).as_hms_micro(),
426    ///     (23, 59, 59, 999_999)
427    /// );
428    /// ```
429    #[inline]
430    pub const fn as_hms_micro(self) -> (u8, u8, u8, u32) {
431        self.time().as_hms_micro()
432    }
433
434    /// Get the clock hour, minute, second, and nanosecond.
435    ///
436    /// ```rust
437    /// # use time_macros::datetime;
438    /// assert_eq!(datetime!(2020-01-01 0:00:00).as_hms_nano(), (0, 0, 0, 0));
439    /// assert_eq!(
440    ///     datetime!(2020-01-01 23:59:59.999_999_999).as_hms_nano(),
441    ///     (23, 59, 59, 999_999_999)
442    /// );
443    /// ```
444    #[inline]
445    pub const fn as_hms_nano(self) -> (u8, u8, u8, u32) {
446        self.time().as_hms_nano()
447    }
448
449    /// Get the clock hour.
450    ///
451    /// The returned value will always be in the range `0..24`.
452    ///
453    /// ```rust
454    /// # use time_macros::datetime;
455    /// assert_eq!(datetime!(2019-01-01 0:00).hour(), 0);
456    /// assert_eq!(datetime!(2019-01-01 23:59:59).hour(), 23);
457    /// ```
458    #[inline]
459    pub const fn hour(self) -> u8 {
460        self.time().hour()
461    }
462
463    /// Get the minute within the hour.
464    ///
465    /// The returned value will always be in the range `0..60`.
466    ///
467    /// ```rust
468    /// # use time_macros::datetime;
469    /// assert_eq!(datetime!(2019-01-01 0:00).minute(), 0);
470    /// assert_eq!(datetime!(2019-01-01 23:59:59).minute(), 59);
471    /// ```
472    #[inline]
473    pub const fn minute(self) -> u8 {
474        self.time().minute()
475    }
476
477    /// Get the second within the minute.
478    ///
479    /// The returned value will always be in the range `0..60`.
480    ///
481    /// ```rust
482    /// # use time_macros::datetime;
483    /// assert_eq!(datetime!(2019-01-01 0:00).second(), 0);
484    /// assert_eq!(datetime!(2019-01-01 23:59:59).second(), 59);
485    /// ```
486    #[inline]
487    pub const fn second(self) -> u8 {
488        self.time().second()
489    }
490
491    /// Get the milliseconds within the second.
492    ///
493    /// The returned value will always be in the range `0..1_000`.
494    ///
495    /// ```rust
496    /// # use time_macros::datetime;
497    /// assert_eq!(datetime!(2019-01-01 0:00).millisecond(), 0);
498    /// assert_eq!(datetime!(2019-01-01 23:59:59.999).millisecond(), 999);
499    /// ```
500    #[inline]
501    pub const fn millisecond(self) -> u16 {
502        self.time().millisecond()
503    }
504
505    /// Get the microseconds within the second.
506    ///
507    /// The returned value will always be in the range `0..1_000_000`.
508    ///
509    /// ```rust
510    /// # use time_macros::datetime;
511    /// assert_eq!(datetime!(2019-01-01 0:00).microsecond(), 0);
512    /// assert_eq!(
513    ///     datetime!(2019-01-01 23:59:59.999_999).microsecond(),
514    ///     999_999
515    /// );
516    /// ```
517    #[inline]
518    pub const fn microsecond(self) -> u32 {
519        self.time().microsecond()
520    }
521
522    /// Get the nanoseconds within the second.
523    ///
524    /// The returned value will always be in the range `0..1_000_000_000`.
525    ///
526    /// ```rust
527    /// # use time_macros::datetime;
528    /// assert_eq!(datetime!(2019-01-01 0:00).nanosecond(), 0);
529    /// assert_eq!(
530    ///     datetime!(2019-01-01 23:59:59.999_999_999).nanosecond(),
531    ///     999_999_999,
532    /// );
533    /// ```
534    #[inline]
535    pub const fn nanosecond(self) -> u32 {
536        self.time().nanosecond()
537    }
538
539    /// Assuming that the existing `PlainDateTime` represents a moment in the provided
540    /// [`UtcOffset`], return an [`OffsetDateTime`].
541    ///
542    /// ```rust
543    /// # use time_macros::{datetime, offset};
544    /// assert_eq!(
545    ///     datetime!(2019-01-01 0:00)
546    ///         .assume_offset(offset!(UTC))
547    ///         .unix_timestamp(),
548    ///     1_546_300_800,
549    /// );
550    /// assert_eq!(
551    ///     datetime!(2019-01-01 0:00)
552    ///         .assume_offset(offset!(-1))
553    ///         .unix_timestamp(),
554    ///     1_546_304_400,
555    /// );
556    /// ```
557    #[inline]
558    pub const fn assume_offset(self, offset: UtcOffset) -> OffsetDateTime {
559        OffsetDateTime::new_in_offset(self.date, self.time, offset)
560    }
561
562    /// Assuming that the existing `PlainDateTime` represents a moment in UTC, return an
563    /// [`OffsetDateTime`].
564    ///
565    /// ```rust
566    /// # use time_macros::datetime;
567    /// assert_eq!(
568    ///     datetime!(2019-01-01 0:00).assume_utc().unix_timestamp(),
569    ///     1_546_300_800,
570    /// );
571    /// ```
572    ///
573    /// **Note**: You may want a [`UtcDateTime`] instead, which can be obtained with the
574    /// [`PlainDateTime::as_utc`] method.
575    #[inline]
576    pub const fn assume_utc(self) -> OffsetDateTime {
577        self.assume_offset(UtcOffset::UTC)
578    }
579
580    /// Assuming that the existing `PlainDateTime` represents a moment in UTC, return a
581    /// [`UtcDateTime`].
582    ///
583    /// ```rust
584    /// # use time_macros::datetime;
585    /// assert_eq!(
586    ///     datetime!(2019-01-01 0:00).as_utc().unix_timestamp(),
587    ///     1_546_300_800,
588    /// );
589    /// ```
590    #[inline]
591    pub const fn as_utc(self) -> UtcDateTime {
592        UtcDateTime::from_plain(self)
593    }
594
595    /// Computes `self + duration`, returning `None` if an overflow occurred.
596    ///
597    /// ```
598    /// # use time::{Date, ext::NumericalDuration};
599    /// # use time_macros::datetime;
600    /// let datetime = Date::MIN.midnight();
601    /// assert_eq!(datetime.checked_add((-2).days()), None);
602    ///
603    /// let datetime = Date::MAX.midnight();
604    /// assert_eq!(datetime.checked_add(1.days()), None);
605    ///
606    /// assert_eq!(
607    ///     datetime!(2019-11-25 15:30).checked_add(27.hours()),
608    ///     Some(datetime!(2019-11-26 18:30))
609    /// );
610    /// ```
611    #[inline]
612    pub const fn checked_add(self, duration: SignedDuration) -> Option<Self> {
613        let (date_adjustment, time) = self.time.adjusting_add(duration);
614        let date = const_try_opt!(self.date.checked_add(duration));
615
616        Some(Self {
617            date: match date_adjustment {
618                util::DateAdjustment::Previous => const_try_opt!(date.previous_day()),
619                util::DateAdjustment::Next => const_try_opt!(date.next_day()),
620                util::DateAdjustment::None => date,
621            },
622            time,
623        })
624    }
625
626    /// Computes `self - duration`, returning `None` if an overflow occurred.
627    ///
628    /// ```
629    /// # use time::{Date, ext::NumericalDuration};
630    /// # use time_macros::datetime;
631    /// let datetime = Date::MIN.midnight();
632    /// assert_eq!(datetime.checked_sub(2.days()), None);
633    ///
634    /// let datetime = Date::MAX.midnight();
635    /// assert_eq!(datetime.checked_sub((-1).days()), None);
636    ///
637    /// assert_eq!(
638    ///     datetime!(2019-11-25 15:30).checked_sub(27.hours()),
639    ///     Some(datetime!(2019-11-24 12:30))
640    /// );
641    /// ```
642    #[inline]
643    pub const fn checked_sub(self, duration: SignedDuration) -> Option<Self> {
644        let (date_adjustment, time) = self.time.adjusting_sub(duration);
645        let date = const_try_opt!(self.date.checked_sub(duration));
646
647        Some(Self {
648            date: match date_adjustment {
649                util::DateAdjustment::Previous => const_try_opt!(date.previous_day()),
650                util::DateAdjustment::Next => const_try_opt!(date.next_day()),
651                util::DateAdjustment::None => date,
652            },
653            time,
654        })
655    }
656
657    /// Computes `self + duration`, saturating value on overflow.
658    ///
659    /// ```
660    /// # use time::{PlainDateTime, ext::NumericalDuration};
661    /// # use time_macros::datetime;
662    /// assert_eq!(
663    ///     PlainDateTime::MIN.saturating_add((-2).days()),
664    ///     PlainDateTime::MIN
665    /// );
666    ///
667    /// assert_eq!(
668    ///     PlainDateTime::MAX.saturating_add(2.days()),
669    ///     PlainDateTime::MAX
670    /// );
671    ///
672    /// assert_eq!(
673    ///     datetime!(2019-11-25 15:30).saturating_add(27.hours()),
674    ///     datetime!(2019-11-26 18:30)
675    /// );
676    /// ```
677    #[inline]
678    pub const fn saturating_add(self, duration: SignedDuration) -> Self {
679        if let Some(datetime) = self.checked_add(duration) {
680            datetime
681        } else if duration.is_negative() {
682            Self::MIN
683        } else {
684            Self::MAX
685        }
686    }
687
688    /// Computes `self - duration`, saturating value on overflow.
689    ///
690    /// ```
691    /// # use time::{PlainDateTime, ext::NumericalDuration};
692    /// # use time_macros::datetime;
693    /// assert_eq!(
694    ///     PlainDateTime::MIN.saturating_sub(2.days()),
695    ///     PlainDateTime::MIN
696    /// );
697    ///
698    /// assert_eq!(
699    ///     PlainDateTime::MAX.saturating_sub((-2).days()),
700    ///     PlainDateTime::MAX
701    /// );
702    ///
703    /// assert_eq!(
704    ///     datetime!(2019-11-25 15:30).saturating_sub(27.hours()),
705    ///     datetime!(2019-11-24 12:30)
706    /// );
707    /// ```
708    #[inline]
709    pub const fn saturating_sub(self, duration: SignedDuration) -> Self {
710        if let Some(datetime) = self.checked_sub(duration) {
711            datetime
712        } else if duration.is_negative() {
713            Self::MAX
714        } else {
715            Self::MIN
716        }
717    }
718}
719
720/// Methods that replace part of the `PlainDateTime`.
721impl PlainDateTime {
722    /// Replace the time, preserving the date.
723    ///
724    /// ```rust
725    /// # use time_macros::{datetime, time};
726    /// assert_eq!(
727    ///     datetime!(2020-01-01 17:00).replace_time(time!(5:00)),
728    ///     datetime!(2020-01-01 5:00)
729    /// );
730    /// ```
731    #[must_use = "This method does not mutate the original `PlainDateTime`."]
732    #[inline]
733    pub const fn replace_time(self, time: Time) -> Self {
734        Self {
735            date: self.date,
736            time,
737        }
738    }
739
740    /// Replace the date, preserving the time.
741    ///
742    /// ```rust
743    /// # use time_macros::{datetime, date};
744    /// assert_eq!(
745    ///     datetime!(2020-01-01 12:00).replace_date(date!(2020-01-30)),
746    ///     datetime!(2020-01-30 12:00)
747    /// );
748    /// ```
749    #[must_use = "This method does not mutate the original `PlainDateTime`."]
750    #[inline]
751    pub const fn replace_date(self, date: Date) -> Self {
752        Self {
753            date,
754            time: self.time,
755        }
756    }
757
758    /// Replace the year. The month and day will be unchanged.
759    ///
760    /// ```rust
761    /// # use time_macros::datetime;
762    /// assert_eq!(
763    ///     datetime!(2022-02-18 12:00).replace_year(2019),
764    ///     Ok(datetime!(2019-02-18 12:00))
765    /// );
766    /// assert!(datetime!(2022-02-18 12:00).replace_year(-1_000_000_000).is_err()); // -1_000_000_000 isn't a valid year
767    /// assert!(datetime!(2022-02-18 12:00).replace_year(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid year
768    /// ```
769    #[must_use = "This method does not mutate the original `PlainDateTime`."]
770    #[inline]
771    pub const fn replace_year(self, year: i32) -> Result<Self, error::ComponentRange> {
772        Ok(Self {
773            date: const_try!(self.date.replace_year(year)),
774            time: self.time,
775        })
776    }
777
778    /// Replace the month of the year.
779    ///
780    /// ```rust
781    /// # use time_macros::datetime;
782    /// # use time::Month;
783    /// assert_eq!(
784    ///     datetime!(2022-02-18 12:00).replace_month(Month::January),
785    ///     Ok(datetime!(2022-01-18 12:00))
786    /// );
787    /// assert!(datetime!(2022-01-30 12:00).replace_month(Month::February).is_err()); // 30 isn't a valid day in February
788    /// ```
789    #[must_use = "This method does not mutate the original `PlainDateTime`."]
790    #[inline]
791    pub const fn replace_month(self, month: Month) -> Result<Self, error::ComponentRange> {
792        Ok(Self {
793            date: const_try!(self.date.replace_month(month)),
794            time: self.time,
795        })
796    }
797
798    /// Replace the day of the month.
799    ///
800    /// ```rust
801    /// # use time_macros::datetime;
802    /// assert_eq!(
803    ///     datetime!(2022-02-18 12:00).replace_day(1),
804    ///     Ok(datetime!(2022-02-01 12:00))
805    /// );
806    /// assert!(datetime!(2022-02-18 12:00).replace_day(0).is_err()); // 00 isn't a valid day
807    /// assert!(datetime!(2022-02-18 12:00).replace_day(30).is_err()); // 30 isn't a valid day in February
808    /// ```
809    #[must_use = "This method does not mutate the original `PlainDateTime`."]
810    #[inline]
811    pub const fn replace_day(self, day: u8) -> Result<Self, error::ComponentRange> {
812        Ok(Self {
813            date: const_try!(self.date.replace_day(day)),
814            time: self.time,
815        })
816    }
817
818    /// Replace the day of the year.
819    ///
820    /// ```rust
821    /// # use time_macros::datetime;
822    /// assert_eq!(datetime!(2022-049 12:00).replace_ordinal(1), Ok(datetime!(2022-001 12:00)));
823    /// assert!(datetime!(2022-049 12:00).replace_ordinal(0).is_err()); // 0 isn't a valid ordinal
824    /// assert!(datetime!(2022-049 12:00).replace_ordinal(366).is_err()); // 2022 isn't a leap year
825    /// ```
826    #[must_use = "This method does not mutate the original `PlainDateTime`."]
827    #[inline]
828    pub const fn replace_ordinal(self, ordinal: u16) -> Result<Self, error::ComponentRange> {
829        Ok(Self {
830            date: const_try!(self.date.replace_ordinal(ordinal)),
831            time: self.time,
832        })
833    }
834
835    /// Truncate to the start of the day, setting the time to midnight.
836    ///
837    /// ```rust
838    /// # use time_macros::datetime;
839    /// assert_eq!(
840    ///     datetime!(2022-02-18 15:30:45.123_456_789).truncate_to_day(),
841    ///     datetime!(2022-02-18 0:00)
842    /// );
843    /// ```
844    #[must_use = "This method does not mutate the original `PlainDateTime`."]
845    #[inline]
846    pub const fn truncate_to_day(self) -> Self {
847        self.replace_time(Time::MIDNIGHT)
848    }
849
850    /// Replace the clock hour.
851    ///
852    /// ```rust
853    /// # use time_macros::datetime;
854    /// assert_eq!(
855    ///     datetime!(2022-02-18 01:02:03.004_005_006).replace_hour(7),
856    ///     Ok(datetime!(2022-02-18 07:02:03.004_005_006))
857    /// );
858    /// assert!(datetime!(2022-02-18 01:02:03.004_005_006).replace_hour(24).is_err()); // 24 isn't a valid hour
859    /// ```
860    #[must_use = "This method does not mutate the original `PlainDateTime`."]
861    #[inline]
862    pub const fn replace_hour(self, hour: u8) -> Result<Self, error::ComponentRange> {
863        Ok(Self {
864            date: self.date,
865            time: const_try!(self.time.replace_hour(hour)),
866        })
867    }
868
869    /// Truncate to the hour, setting the minute, second, and subsecond components to zero.
870    ///
871    /// ```rust
872    /// # use time_macros::datetime;
873    /// assert_eq!(
874    ///     datetime!(2022-02-18 15:30:45.123_456_789).truncate_to_hour(),
875    ///     datetime!(2022-02-18 15:00)
876    /// );
877    /// ```
878    #[must_use = "This method does not mutate the original `PlainDateTime`."]
879    #[inline]
880    pub const fn truncate_to_hour(self) -> Self {
881        self.replace_time(self.time.truncate_to_hour())
882    }
883
884    /// Replace the minutes within the hour.
885    ///
886    /// ```rust
887    /// # use time_macros::datetime;
888    /// assert_eq!(
889    ///     datetime!(2022-02-18 01:02:03.004_005_006).replace_minute(7),
890    ///     Ok(datetime!(2022-02-18 01:07:03.004_005_006))
891    /// );
892    /// assert!(datetime!(2022-02-18 01:02:03.004_005_006).replace_minute(60).is_err()); // 60 isn't a valid minute
893    /// ```
894    #[must_use = "This method does not mutate the original `PlainDateTime`."]
895    #[inline]
896    pub const fn replace_minute(self, minute: u8) -> Result<Self, error::ComponentRange> {
897        Ok(Self {
898            date: self.date,
899            time: const_try!(self.time.replace_minute(minute)),
900        })
901    }
902
903    /// Truncate to the minute, setting the second and subsecond components to zero.
904    ///
905    /// ```rust
906    /// # use time_macros::datetime;
907    /// assert_eq!(
908    ///     datetime!(2022-02-18 15:30:45.123_456_789).truncate_to_minute(),
909    ///     datetime!(2022-02-18 15:30)
910    /// );
911    /// ```
912    #[must_use = "This method does not mutate the original `PlainDateTime`."]
913    #[inline]
914    pub const fn truncate_to_minute(self) -> Self {
915        self.replace_time(self.time.truncate_to_minute())
916    }
917
918    /// Replace the seconds within the minute.
919    ///
920    /// ```rust
921    /// # use time_macros::datetime;
922    /// assert_eq!(
923    ///     datetime!(2022-02-18 01:02:03.004_005_006).replace_second(7),
924    ///     Ok(datetime!(2022-02-18 01:02:07.004_005_006))
925    /// );
926    /// assert!(datetime!(2022-02-18 01:02:03.004_005_006).replace_second(60).is_err()); // 60 isn't a valid second
927    /// ```
928    #[must_use = "This method does not mutate the original `PlainDateTime`."]
929    #[inline]
930    pub const fn replace_second(self, second: u8) -> Result<Self, error::ComponentRange> {
931        Ok(Self {
932            date: self.date,
933            time: const_try!(self.time.replace_second(second)),
934        })
935    }
936
937    /// Truncate to the second, setting the subsecond components to zero.
938    ///
939    /// ```rust
940    /// # use time_macros::datetime;
941    /// assert_eq!(
942    ///     datetime!(2022-02-18 15:30:45.123_456_789).truncate_to_second(),
943    ///     datetime!(2022-02-18 15:30:45)
944    /// );
945    /// ```
946    #[must_use = "This method does not mutate the original `PlainDateTime`."]
947    #[inline]
948    pub const fn truncate_to_second(self) -> Self {
949        self.replace_time(self.time.truncate_to_second())
950    }
951
952    /// Replace the milliseconds within the second.
953    ///
954    /// ```rust
955    /// # use time_macros::datetime;
956    /// assert_eq!(
957    ///     datetime!(2022-02-18 01:02:03.004_005_006).replace_millisecond(7),
958    ///     Ok(datetime!(2022-02-18 01:02:03.007))
959    /// );
960    /// assert!(datetime!(2022-02-18 01:02:03.004_005_006).replace_millisecond(1_000).is_err()); // 1_000 isn't a valid millisecond
961    /// ```
962    #[must_use = "This method does not mutate the original `PlainDateTime`."]
963    #[inline]
964    pub const fn replace_millisecond(
965        self,
966        millisecond: u16,
967    ) -> Result<Self, error::ComponentRange> {
968        Ok(Self {
969            date: self.date,
970            time: const_try!(self.time.replace_millisecond(millisecond)),
971        })
972    }
973
974    /// Truncate to the millisecond, setting the microsecond and nanosecond components to zero.
975    ///
976    /// ```rust
977    /// # use time_macros::datetime;
978    /// assert_eq!(
979    ///     datetime!(2022-02-18 15:30:45.123_456_789).truncate_to_millisecond(),
980    ///     datetime!(2022-02-18 15:30:45.123)
981    /// );
982    /// ```
983    #[must_use = "This method does not mutate the original `PlainDateTime`."]
984    #[inline]
985    pub const fn truncate_to_millisecond(self) -> Self {
986        self.replace_time(self.time.truncate_to_millisecond())
987    }
988
989    /// Replace the microseconds within the second.
990    ///
991    /// ```rust
992    /// # use time_macros::datetime;
993    /// assert_eq!(
994    ///     datetime!(2022-02-18 01:02:03.004_005_006).replace_microsecond(7_008),
995    ///     Ok(datetime!(2022-02-18 01:02:03.007_008))
996    /// );
997    /// assert!(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
998    /// ```
999    #[must_use = "This method does not mutate the original `PlainDateTime`."]
1000    #[inline]
1001    pub const fn replace_microsecond(
1002        self,
1003        microsecond: u32,
1004    ) -> Result<Self, error::ComponentRange> {
1005        Ok(Self {
1006            date: self.date,
1007            time: const_try!(self.time.replace_microsecond(microsecond)),
1008        })
1009    }
1010
1011    /// Truncate to the microsecond, setting the nanosecond component to zero.
1012    ///
1013    /// ```rust
1014    /// # use time_macros::datetime;
1015    /// assert_eq!(
1016    ///     datetime!(2022-02-18 15:30:45.123_456_789).truncate_to_microsecond(),
1017    ///     datetime!(2022-02-18 15:30:45.123_456)
1018    /// );
1019    /// ```
1020    #[must_use = "This method does not mutate the original `PlainDateTime`."]
1021    #[inline]
1022    pub const fn truncate_to_microsecond(self) -> Self {
1023        self.replace_time(self.time.truncate_to_microsecond())
1024    }
1025
1026    /// Replace the nanoseconds within the second.
1027    ///
1028    /// ```rust
1029    /// # use time_macros::datetime;
1030    /// assert_eq!(
1031    ///     datetime!(2022-02-18 01:02:03.004_005_006).replace_nanosecond(7_008_009),
1032    ///     Ok(datetime!(2022-02-18 01:02:03.007_008_009))
1033    /// );
1034    /// assert!(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
1035    /// ```
1036    #[must_use = "This method does not mutate the original `PlainDateTime`."]
1037    #[inline]
1038    pub const fn replace_nanosecond(self, nanosecond: u32) -> Result<Self, error::ComponentRange> {
1039        Ok(Self {
1040            date: self.date,
1041            time: const_try!(self.time.replace_nanosecond(nanosecond)),
1042        })
1043    }
1044}
1045
1046#[cfg(feature = "formatting")]
1047impl PlainDateTime {
1048    /// Format the `PlainDateTime` using the provided [format ///
1049    /// description](crate::format_description).
1050    #[inline]
1051    pub fn format_into(
1052        self,
1053        output: &mut (impl io::Write + ?Sized),
1054        format: &(impl Formattable + ?Sized),
1055    ) -> Result<usize, error::Format> {
1056        let mut output = crate::formatting::Output {
1057            bytes_written: 0,
1058            output,
1059        };
1060        try_likely_ok!(format.format_into(
1061            &mut output,
1062            &self,
1063            &mut Default::default(),
1064            PrivateMethod,
1065        ));
1066        Ok(output.bytes_written)
1067    }
1068
1069    /// Format the `PlainDateTime` using the provided [format
1070    /// description](crate::format_description).
1071    ///
1072    /// ```rust
1073    /// # use time::format_description;
1074    /// # use time_macros::datetime;
1075    /// let format = format_description::parse_borrowed::<3>(
1076    ///     "[year]-[month]-[day] [hour]:[minute]:[second]"
1077    /// )?;
1078    /// assert_eq!(
1079    ///     datetime!(2020-01-02 03:04:05).format(&format)?,
1080    ///     "2020-01-02 03:04:05"
1081    /// );
1082    /// # Ok::<_, time::Error>(())
1083    /// ```
1084    #[inline]
1085    pub fn format(self, format: &(impl Formattable + ?Sized)) -> Result<String, error::Format> {
1086        format.format(&self, &mut Default::default(), PrivateMethod)
1087    }
1088}
1089
1090#[cfg(feature = "parsing")]
1091impl PlainDateTime {
1092    /// Parse a `PlainDateTime` from the input using the provided [format
1093    /// description](crate::format_description).
1094    ///
1095    /// ```rust
1096    /// # use time::PlainDateTime;
1097    /// # use time_macros::{datetime, format_description};
1098    /// let format = format_description!("[year]-[month]-[day] [hour]:[minute]:[second]");
1099    /// assert_eq!(
1100    ///     PlainDateTime::parse("2020-01-02 03:04:05", &format)?,
1101    ///     datetime!(2020-01-02 03:04:05)
1102    /// );
1103    /// # Ok::<_, time::Error>(())
1104    /// ```
1105    #[inline]
1106    pub fn parse(
1107        input: &str,
1108        description: &(impl Parsable + ?Sized),
1109    ) -> Result<Self, error::Parse> {
1110        description.parse_plain_date_time(input.as_bytes(), None, PrivateMethod)
1111    }
1112
1113    /// Parse a `PlainDateTime` from the input using the provided [format
1114    /// description](crate::format_description) and default values.
1115    ///
1116    /// ```rust
1117    /// # use time::PlainDateTime;
1118    /// # use time::parsing::Parsed;
1119    /// # use time_macros::{datetime, format_description};
1120    /// let format = format_description!("[year]-[month]-[day]");
1121    /// let defaults = Parsed::new().with_hour_24(12).expect("12 is a valid hour");
1122    /// assert_eq!(
1123    ///     PlainDateTime::parse_with_defaults(b"2020-01-02", &format, defaults)?,
1124    ///     datetime!(2020-01-02 12:00)
1125    /// );
1126    /// # Ok::<_, time::Error>(())
1127    /// ```
1128    #[inline]
1129    pub fn parse_with_defaults(
1130        input: &[u8],
1131        description: &(impl Parsable + ?Sized),
1132        defaults: Parsed,
1133    ) -> Result<Self, error::Parse> {
1134        description.parse_plain_date_time(input, Some(defaults), PrivateMethod)
1135    }
1136}
1137
1138// This no longer needs special handling, as the format is fixed and doesn't require anything
1139// advanced. Trait impls can't be deprecated and the info is still useful for other types
1140// implementing `SmartDisplay`, so leave it as-is for now.
1141impl SmartDisplay for PlainDateTime {
1142    type Metadata = ();
1143
1144    #[inline]
1145    fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Self> {
1146        let width = smart_display::padded_width_of!(self.date, " ", self.time);
1147        Metadata::new(width, self, ())
1148    }
1149
1150    #[inline]
1151    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1152        fmt::Display::fmt(self, f)
1153    }
1154}
1155
1156impl PlainDateTime {
1157    /// The maximum number of bytes that the `fmt_into_buffer` method will write, which is also used
1158    /// for the `Display` implementation.
1159    pub(crate) const DISPLAY_BUFFER_SIZE: usize =
1160        Date::DISPLAY_BUFFER_SIZE + Time::DISPLAY_BUFFER_SIZE + 1;
1161
1162    /// Format the `PlainDateTime` into the provided buffer, returning the number of bytes written.
1163    #[inline]
1164    pub(crate) fn fmt_into_buffer(
1165        self,
1166        buf: &mut [MaybeUninit<u8>; Self::DISPLAY_BUFFER_SIZE],
1167    ) -> usize {
1168        // Safety: The buffer is large enough that the first chunk is in bounds.
1169        let date_len = self
1170            .date
1171            .fmt_into_buffer(unsafe { buf.first_chunk_mut().unwrap_unchecked() });
1172        buf[date_len].write(b' ');
1173        // Safety: The buffer is large enough that the first chunk is in bounds.
1174        let time_len = self
1175            .time
1176            .fmt_into_buffer(unsafe { buf[date_len + 1..].first_chunk_mut().unwrap_unchecked() });
1177        date_len + time_len + 1
1178    }
1179}
1180
1181impl fmt::Display for PlainDateTime {
1182    #[inline]
1183    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1184        let mut buf = [MaybeUninit::uninit(); Self::DISPLAY_BUFFER_SIZE];
1185        let len = self.fmt_into_buffer(&mut buf);
1186        // Safety: All bytes up to `len` have been initialized with ASCII characters.
1187        let s = unsafe { str_from_raw_parts(buf.as_ptr().cast(), len) };
1188        f.pad(s)
1189    }
1190}
1191
1192impl fmt::Debug for PlainDateTime {
1193    #[inline]
1194    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1195        fmt::Display::fmt(self, f)
1196    }
1197}
1198
1199impl Add<SignedDuration> for PlainDateTime {
1200    type Output = Self;
1201
1202    /// # Panics
1203    ///
1204    /// This may panic if an overflow occurs.
1205    #[inline]
1206    #[track_caller]
1207    fn add(self, duration: SignedDuration) -> Self::Output {
1208        self.checked_add(duration)
1209            .expect("resulting value is out of range")
1210    }
1211}
1212
1213impl Add<StdDuration> for PlainDateTime {
1214    type Output = Self;
1215
1216    /// # Panics
1217    ///
1218    /// This may panic if an overflow occurs.
1219    #[inline]
1220    #[track_caller]
1221    fn add(self, duration: StdDuration) -> Self::Output {
1222        let (is_next_day, time) = self.time.adjusting_add_std(duration);
1223
1224        Self {
1225            date: if is_next_day {
1226                (self.date + duration)
1227                    .next_day()
1228                    .expect("resulting value is out of range")
1229            } else {
1230                self.date + duration
1231            },
1232            time,
1233        }
1234    }
1235}
1236
1237impl AddAssign<SignedDuration> for PlainDateTime {
1238    /// # Panics
1239    ///
1240    /// This may panic if an overflow occurs.
1241    #[inline]
1242    #[track_caller]
1243    fn add_assign(&mut self, duration: SignedDuration) {
1244        *self = *self + duration;
1245    }
1246}
1247
1248impl AddAssign<StdDuration> for PlainDateTime {
1249    /// # Panics
1250    ///
1251    /// This may panic if an overflow occurs.
1252    #[inline]
1253    #[track_caller]
1254    fn add_assign(&mut self, duration: StdDuration) {
1255        *self = *self + duration;
1256    }
1257}
1258
1259impl Sub<SignedDuration> for PlainDateTime {
1260    type Output = Self;
1261
1262    /// # Panics
1263    ///
1264    /// This may panic if an overflow occurs.
1265    #[inline]
1266    #[track_caller]
1267    fn sub(self, duration: SignedDuration) -> Self::Output {
1268        self.checked_sub(duration)
1269            .expect("resulting value is out of range")
1270    }
1271}
1272
1273impl Sub<StdDuration> for PlainDateTime {
1274    type Output = Self;
1275
1276    /// # Panics
1277    ///
1278    /// This may panic if an overflow occurs.
1279    #[inline]
1280    #[track_caller]
1281    fn sub(self, duration: StdDuration) -> Self::Output {
1282        let (is_previous_day, time) = self.time.adjusting_sub_std(duration);
1283
1284        Self {
1285            date: if is_previous_day {
1286                (self.date - duration)
1287                    .previous_day()
1288                    .expect("resulting value is out of range")
1289            } else {
1290                self.date - duration
1291            },
1292            time,
1293        }
1294    }
1295}
1296
1297impl SubAssign<SignedDuration> for PlainDateTime {
1298    /// # Panics
1299    ///
1300    /// This may panic if an overflow occurs.
1301    #[inline]
1302    #[track_caller]
1303    fn sub_assign(&mut self, duration: SignedDuration) {
1304        *self = *self - duration;
1305    }
1306}
1307
1308impl SubAssign<StdDuration> for PlainDateTime {
1309    /// # Panics
1310    ///
1311    /// This may panic if an overflow occurs.
1312    #[inline]
1313    #[track_caller]
1314    fn sub_assign(&mut self, duration: StdDuration) {
1315        *self = *self - duration;
1316    }
1317}
1318
1319impl Sub for PlainDateTime {
1320    type Output = SignedDuration;
1321
1322    #[inline]
1323    fn sub(self, rhs: Self) -> Self::Output {
1324        (self.date - rhs.date) + (self.time - rhs.time)
1325    }
1326}