Coverage Report

Created: 2026-01-17 07:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/time-0.3.45/src/date.rs
Line
Count
Source
1
//! The [`Date`] struct and its associated `impl`s.
2
3
#[cfg(feature = "formatting")]
4
use alloc::string::String;
5
use core::num::NonZero;
6
use core::ops::{Add, Sub};
7
use core::time::Duration as StdDuration;
8
use core::{cmp, fmt};
9
#[cfg(feature = "formatting")]
10
use std::io;
11
12
use deranged::RangedI32;
13
use num_conv::prelude::*;
14
use powerfmt::ext::FormatterExt;
15
use powerfmt::smart_display::{self, FormatterOptions, Metadata, SmartDisplay};
16
17
use crate::convert::*;
18
use crate::ext::DigitCount;
19
#[cfg(feature = "formatting")]
20
use crate::formatting::Formattable;
21
use crate::internal_macros::{
22
    const_try, const_try_opt, div_floor, ensure_ranged, impl_add_assign, impl_sub_assign,
23
};
24
#[cfg(feature = "parsing")]
25
use crate::parsing::Parsable;
26
use crate::util::{days_in_year, is_leap_year, weeks_in_year};
27
use crate::{error, Duration, Month, PrimitiveDateTime, Time, Weekday};
28
29
type Year = RangedI32<MIN_YEAR, MAX_YEAR>;
30
31
/// The minimum valid year.
32
pub(crate) const MIN_YEAR: i32 = if cfg!(feature = "large-dates") {
33
    -999_999
34
} else {
35
    -9999
36
};
37
/// The maximum valid year.
38
pub(crate) const MAX_YEAR: i32 = if cfg!(feature = "large-dates") {
39
    999_999
40
} else {
41
    9999
42
};
43
44
/// Date in the proleptic Gregorian calendar.
45
///
46
/// By default, years between ±9999 inclusive are representable. This can be expanded to ±999,999
47
/// inclusive by enabling the `large-dates` crate feature. Doing so has performance implications
48
/// and introduces some ambiguities when parsing.
49
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
50
pub struct Date {
51
    /// Bitpacked field containing the year, ordinal, and whether the year is a leap year.
52
    // |     x      | xxxxxxxxxxxxxxxxxxxxx |       x       | xxxxxxxxx |
53
    // |   1 bit    |        21 bits        |     1 bit     |  9 bits   |
54
    // | unassigned |         year          | is leap year? |  ordinal  |
55
    // The year is 15 bits when `large-dates` is not enabled.
56
    value: NonZero<i32>,
57
}
58
59
impl Date {
60
    /// Provide a representation of `Date` as a `i32`. This value can be used for equality, hashing,
61
    /// and ordering.
62
    ///
63
    /// **Note**: This value is explicitly signed, so do not cast this to or treat this as an
64
    /// unsigned integer. Doing so will lead to incorrect results for values with differing
65
    /// signs.
66
    #[inline]
67
0
    pub(crate) const fn as_i32(self) -> i32 {
68
0
        self.value.get()
69
0
    }
70
71
    /// The Unix epoch: 1970-01-01
72
    // Safety: `ordinal` is not zero.
73
    pub(crate) const UNIX_EPOCH: Self = unsafe { Self::__from_ordinal_date_unchecked(1970, 1) };
74
75
    /// The minimum valid `Date`.
76
    ///
77
    /// The value of this may vary depending on the feature flags enabled.
78
    // Safety: `ordinal` is not zero.
79
    pub const MIN: Self = unsafe { Self::__from_ordinal_date_unchecked(MIN_YEAR, 1) };
80
81
    /// The maximum valid `Date`.
82
    ///
83
    /// The value of this may vary depending on the feature flags enabled.
84
    // Safety: `ordinal` is not zero.
85
    pub const MAX: Self =
86
        unsafe { Self::__from_ordinal_date_unchecked(MAX_YEAR, days_in_year(MAX_YEAR)) };
87
88
    /// Construct a `Date` from its internal representation, the validity of which must be
89
    /// guaranteed by the caller.
90
    ///
91
    /// # Safety
92
    ///
93
    /// - `ordinal` must be non-zero and at most the number of days in `year`
94
    /// - `is_leap_year` must be `true` if and only if `year` is a leap year
95
    #[inline]
96
    #[track_caller]
97
83.4k
    const unsafe fn from_parts(year: i32, is_leap_year: bool, ordinal: u16) -> Self {
98
83.4k
        debug_assert!(year >= MIN_YEAR);
99
83.4k
        debug_assert!(year <= MAX_YEAR);
100
83.4k
        debug_assert!(ordinal != 0);
101
83.4k
        debug_assert!(ordinal <= days_in_year(year));
102
83.4k
        debug_assert!(crate::util::is_leap_year(year) == is_leap_year);
103
104
83.4k
        Self {
105
83.4k
            // Safety: `ordinal` is not zero.
106
83.4k
            value: unsafe {
107
83.4k
                NonZero::new_unchecked((year << 10) | ((is_leap_year as i32) << 9) | ordinal as i32)
108
83.4k
            },
109
83.4k
        }
110
83.4k
    }
<time::date::Date>::from_parts
Line
Count
Source
97
83.4k
    const unsafe fn from_parts(year: i32, is_leap_year: bool, ordinal: u16) -> Self {
98
83.4k
        debug_assert!(year >= MIN_YEAR);
99
83.4k
        debug_assert!(year <= MAX_YEAR);
100
83.4k
        debug_assert!(ordinal != 0);
101
83.4k
        debug_assert!(ordinal <= days_in_year(year));
102
83.4k
        debug_assert!(crate::util::is_leap_year(year) == is_leap_year);
103
104
83.4k
        Self {
105
83.4k
            // Safety: `ordinal` is not zero.
106
83.4k
            value: unsafe {
107
83.4k
                NonZero::new_unchecked((year << 10) | ((is_leap_year as i32) << 9) | ordinal as i32)
108
83.4k
            },
109
83.4k
        }
110
83.4k
    }
Unexecuted instantiation: <time::date::Date>::from_parts
111
112
    /// Construct a `Date` from the year and ordinal values, the validity of which must be
113
    /// guaranteed by the caller.
114
    ///
115
    /// # Safety
116
    ///
117
    /// `ordinal` must be non-zero and at most the number of days in `year`. `year` should be in the
118
    /// range `MIN_YEAR..=MAX_YEAR`, but this is not a safety invariant.
119
    #[doc(hidden)]
120
    #[inline]
121
    #[track_caller]
122
0
    pub const unsafe fn __from_ordinal_date_unchecked(year: i32, ordinal: u16) -> Self {
123
        // Safety: The caller must guarantee that `ordinal` is not zero.
124
0
        unsafe { Self::from_parts(year, is_leap_year(year), ordinal) }
125
0
    }
Unexecuted instantiation: <time::date::Date>::__from_ordinal_date_unchecked
Unexecuted instantiation: <time::date::Date>::__from_ordinal_date_unchecked
126
127
    /// Attempt to create a `Date` from the year, month, and day.
128
    ///
129
    /// ```rust
130
    /// # use time::{Date, Month};
131
    /// assert!(Date::from_calendar_date(2019, Month::January, 1).is_ok());
132
    /// assert!(Date::from_calendar_date(2019, Month::December, 31).is_ok());
133
    /// ```
134
    ///
135
    /// ```rust
136
    /// # use time::{Date, Month};
137
    /// assert!(Date::from_calendar_date(2019, Month::February, 29).is_err()); // 2019 isn't a leap year.
138
    /// ```
139
    #[inline]
140
0
    pub const fn from_calendar_date(
141
0
        year: i32,
142
0
        month: Month,
143
0
        day: u8,
144
0
    ) -> Result<Self, error::ComponentRange> {
145
        /// Cumulative days through the beginning of a month in both common and leap years.
146
        const DAYS_CUMULATIVE_COMMON_LEAP: [[u16; 12]; 2] = [
147
            [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
148
            [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335],
149
        ];
150
151
0
        ensure_ranged!(Year: year);
152
0
        match day {
153
0
            1..=28 => {}
154
0
            29..=31 if day <= month.length(year) => {}
155
            _ => {
156
0
                return Err(error::ComponentRange {
157
0
                    name: "day",
158
0
                    minimum: 1,
159
0
                    maximum: month.length(year) as i64,
160
0
                    value: day as i64,
161
0
                    conditional_message: Some("for the given month and year"),
162
0
                });
163
            }
164
        }
165
166
        // Safety: `ordinal` is not zero.
167
0
        Ok(unsafe {
168
0
            Self::__from_ordinal_date_unchecked(
169
0
                year,
170
0
                DAYS_CUMULATIVE_COMMON_LEAP[is_leap_year(year) as usize][month as usize - 1]
171
0
                    + day as u16,
172
0
            )
173
0
        })
174
0
    }
Unexecuted instantiation: <time::date::Date>::from_calendar_date
Unexecuted instantiation: <time::date::Date>::from_calendar_date
175
176
    /// Attempt to create a `Date` from the year and ordinal day number.
177
    ///
178
    /// ```rust
179
    /// # use time::Date;
180
    /// assert!(Date::from_ordinal_date(2019, 1).is_ok());
181
    /// assert!(Date::from_ordinal_date(2019, 365).is_ok());
182
    /// ```
183
    ///
184
    /// ```rust
185
    /// # use time::Date;
186
    /// assert!(Date::from_ordinal_date(2019, 366).is_err()); // 2019 isn't a leap year.
187
    /// ```
188
    #[inline]
189
0
    pub const fn from_ordinal_date(year: i32, ordinal: u16) -> Result<Self, error::ComponentRange> {
190
0
        ensure_ranged!(Year: year);
191
0
        match ordinal {
192
0
            1..=365 => {}
193
0
            366 if is_leap_year(year) => {}
194
            _ => {
195
0
                return Err(error::ComponentRange {
196
0
                    name: "ordinal",
197
0
                    minimum: 1,
198
0
                    maximum: days_in_year(year) as i64,
199
0
                    value: ordinal as i64,
200
0
                    conditional_message: Some("for the given year"),
201
0
                });
202
            }
203
        }
204
205
        // Safety: `ordinal` is not zero.
206
0
        Ok(unsafe { Self::__from_ordinal_date_unchecked(year, ordinal) })
207
0
    }
208
209
    /// Attempt to create a `Date` from the ISO year, week, and weekday.
210
    ///
211
    /// ```rust
212
    /// # use time::{Date, Weekday::*};
213
    /// assert!(Date::from_iso_week_date(2019, 1, Monday).is_ok());
214
    /// assert!(Date::from_iso_week_date(2019, 1, Tuesday).is_ok());
215
    /// assert!(Date::from_iso_week_date(2020, 53, Friday).is_ok());
216
    /// ```
217
    ///
218
    /// ```rust
219
    /// # use time::{Date, Weekday::*};
220
    /// assert!(Date::from_iso_week_date(2019, 53, Monday).is_err()); // 2019 doesn't have 53 weeks.
221
    /// ```
222
0
    pub const fn from_iso_week_date(
223
0
        year: i32,
224
0
        week: u8,
225
0
        weekday: Weekday,
226
0
    ) -> Result<Self, error::ComponentRange> {
227
0
        ensure_ranged!(Year: year);
228
0
        match week {
229
0
            1..=52 => {}
230
0
            53 if week <= weeks_in_year(year) => {}
231
            _ => {
232
0
                return Err(error::ComponentRange {
233
0
                    name: "week",
234
0
                    minimum: 1,
235
0
                    maximum: weeks_in_year(year) as i64,
236
0
                    value: week as i64,
237
0
                    conditional_message: Some("for the given year"),
238
0
                });
239
            }
240
        }
241
242
0
        let adj_year = year - 1;
243
0
        let raw = 365 * adj_year + div_floor!(adj_year, 4) - div_floor!(adj_year, 100)
244
0
            + div_floor!(adj_year, 400);
245
0
        let jan_4 = match (raw % 7) as i8 {
246
0
            -6 | 1 => 8,
247
0
            -5 | 2 => 9,
248
0
            -4 | 3 => 10,
249
0
            -3 | 4 => 4,
250
0
            -2 | 5 => 5,
251
0
            -1 | 6 => 6,
252
0
            _ => 7,
253
        };
254
0
        let ordinal = week as i16 * 7 + weekday.number_from_monday() as i16 - jan_4;
255
256
0
        Ok(if ordinal <= 0 {
257
            // Safety: `ordinal` is not zero.
258
            unsafe {
259
0
                Self::__from_ordinal_date_unchecked(
260
0
                    year - 1,
261
0
                    (ordinal as u16).wrapping_add(days_in_year(year - 1)),
262
                )
263
            }
264
0
        } else if ordinal > days_in_year(year) as i16 {
265
            // Safety: `ordinal` is not zero.
266
            unsafe {
267
0
                Self::__from_ordinal_date_unchecked(year + 1, ordinal as u16 - days_in_year(year))
268
            }
269
        } else {
270
            // Safety: `ordinal` is not zero.
271
0
            unsafe { Self::__from_ordinal_date_unchecked(year, ordinal as u16) }
272
        })
273
0
    }
274
275
    /// Create a `Date` from the Julian day.
276
    ///
277
    /// The algorithm to perform this conversion is derived from one provided by Peter Baum; it is
278
    /// freely available [here](https://www.researchgate.net/publication/316558298_Date_Algorithms).
279
    ///
280
    /// ```rust
281
    /// # use time::Date;
282
    /// # use time_macros::date;
283
    /// assert_eq!(Date::from_julian_day(0), Ok(date!(-4713 - 11 - 24)));
284
    /// assert_eq!(Date::from_julian_day(2_451_545), Ok(date!(2000-01-01)));
285
    /// assert_eq!(Date::from_julian_day(2_458_485), Ok(date!(2019-01-01)));
286
    /// assert_eq!(Date::from_julian_day(2_458_849), Ok(date!(2019-12-31)));
287
    /// ```
288
    #[doc(alias = "from_julian_date")]
289
    #[inline]
290
83.4k
    pub const fn from_julian_day(julian_day: i32) -> Result<Self, error::ComponentRange> {
291
        type JulianDay = RangedI32<{ Date::MIN.to_julian_day() }, { Date::MAX.to_julian_day() }>;
292
83.4k
        ensure_ranged!(JulianDay: julian_day);
293
        // Safety: The Julian day number is in range.
294
83.4k
        Ok(unsafe { Self::from_julian_day_unchecked(julian_day) })
295
83.4k
    }
<time::date::Date>::from_julian_day
Line
Count
Source
290
83.4k
    pub const fn from_julian_day(julian_day: i32) -> Result<Self, error::ComponentRange> {
291
        type JulianDay = RangedI32<{ Date::MIN.to_julian_day() }, { Date::MAX.to_julian_day() }>;
292
83.4k
        ensure_ranged!(JulianDay: julian_day);
293
        // Safety: The Julian day number is in range.
294
83.4k
        Ok(unsafe { Self::from_julian_day_unchecked(julian_day) })
295
83.4k
    }
Unexecuted instantiation: <time::date::Date>::from_julian_day
296
297
    /// Create a `Date` from the Julian day.
298
    ///
299
    /// # Safety
300
    ///
301
    /// The provided Julian day number must be between `Date::MIN.to_julian_day()` and
302
    /// `Date::MAX.to_julian_day()` inclusive.
303
    #[inline]
304
83.4k
    pub(crate) const unsafe fn from_julian_day_unchecked(julian_day: i32) -> Self {
305
83.4k
        debug_assert!(julian_day >= Self::MIN.to_julian_day());
306
83.4k
        debug_assert!(julian_day <= Self::MAX.to_julian_day());
307
308
        const ERAS: u32 = 5_949;
309
        // Rata Die shift:
310
        const D_SHIFT: u32 = 146097 * ERAS - 1_721_060;
311
        // Year shift:
312
        const Y_SHIFT: u32 = 400 * ERAS;
313
314
        const CEN_MUL: u32 = ((4u64 << 47) / 146_097) as u32;
315
        const JUL_MUL: u32 = ((4u64 << 40) / 1_461 + 1) as u32;
316
        const CEN_CUT: u32 = ((365u64 << 32) / 36_525) as u32;
317
318
83.4k
        let day = julian_day.wrapping_add_unsigned(D_SHIFT) as u32;
319
83.4k
        let c_n = (day as u64 * CEN_MUL as u64) >> 15;
320
83.4k
        let cen = (c_n >> 32) as u32;
321
83.4k
        let cpt = c_n as u32;
322
83.4k
        let ijy = (cpt > CEN_CUT) || (cen % 4 == 0);
323
83.4k
        let jul = day - cen / 4 + cen;
324
83.4k
        let y_n = (jul as u64 * JUL_MUL as u64) >> 8;
325
83.4k
        let yrs = (y_n >> 32) as u32;
326
83.4k
        let ypt = y_n as u32;
327
328
83.4k
        let year = yrs.wrapping_sub(Y_SHIFT) as i32;
329
83.4k
        let ordinal = ((ypt as u64 * 1_461) >> 34) as u32 + ijy as u32;
330
83.4k
        let leap = (yrs % 4 == 0) & ijy;
331
332
        // Safety: `ordinal` is not zero and `is_leap_year` is correct, so long as the Julian day
333
        // number is in range, which is guaranteed by the caller.
334
83.4k
        unsafe { Self::from_parts(year, leap, ordinal as u16) }
335
83.4k
    }
<time::date::Date>::from_julian_day_unchecked
Line
Count
Source
304
83.4k
    pub(crate) const unsafe fn from_julian_day_unchecked(julian_day: i32) -> Self {
305
83.4k
        debug_assert!(julian_day >= Self::MIN.to_julian_day());
306
83.4k
        debug_assert!(julian_day <= Self::MAX.to_julian_day());
307
308
        const ERAS: u32 = 5_949;
309
        // Rata Die shift:
310
        const D_SHIFT: u32 = 146097 * ERAS - 1_721_060;
311
        // Year shift:
312
        const Y_SHIFT: u32 = 400 * ERAS;
313
314
        const CEN_MUL: u32 = ((4u64 << 47) / 146_097) as u32;
315
        const JUL_MUL: u32 = ((4u64 << 40) / 1_461 + 1) as u32;
316
        const CEN_CUT: u32 = ((365u64 << 32) / 36_525) as u32;
317
318
83.4k
        let day = julian_day.wrapping_add_unsigned(D_SHIFT) as u32;
319
83.4k
        let c_n = (day as u64 * CEN_MUL as u64) >> 15;
320
83.4k
        let cen = (c_n >> 32) as u32;
321
83.4k
        let cpt = c_n as u32;
322
83.4k
        let ijy = (cpt > CEN_CUT) || (cen % 4 == 0);
323
83.4k
        let jul = day - cen / 4 + cen;
324
83.4k
        let y_n = (jul as u64 * JUL_MUL as u64) >> 8;
325
83.4k
        let yrs = (y_n >> 32) as u32;
326
83.4k
        let ypt = y_n as u32;
327
328
83.4k
        let year = yrs.wrapping_sub(Y_SHIFT) as i32;
329
83.4k
        let ordinal = ((ypt as u64 * 1_461) >> 34) as u32 + ijy as u32;
330
83.4k
        let leap = (yrs % 4 == 0) & ijy;
331
332
        // Safety: `ordinal` is not zero and `is_leap_year` is correct, so long as the Julian day
333
        // number is in range, which is guaranteed by the caller.
334
83.4k
        unsafe { Self::from_parts(year, leap, ordinal as u16) }
335
83.4k
    }
Unexecuted instantiation: <time::date::Date>::from_julian_day_unchecked
336
337
    /// Whether `is_leap_year(self.year())` is `true`.
338
    ///
339
    /// This method is optimized to take advantage of the fact that the value is pre-computed upon
340
    /// construction and stored in the bitpacked struct.
341
    #[inline]
342
166k
    const fn is_in_leap_year(self) -> bool {
343
166k
        (self.value.get() >> 9) & 1 == 1
344
166k
    }
<time::date::Date>::is_in_leap_year
Line
Count
Source
342
166k
    const fn is_in_leap_year(self) -> bool {
343
166k
        (self.value.get() >> 9) & 1 == 1
344
166k
    }
Unexecuted instantiation: <time::date::Date>::is_in_leap_year
345
346
    /// Get the year of the date.
347
    ///
348
    /// ```rust
349
    /// # use time_macros::date;
350
    /// assert_eq!(date!(2019-01-01).year(), 2019);
351
    /// assert_eq!(date!(2019-12-31).year(), 2019);
352
    /// assert_eq!(date!(2020-01-01).year(), 2020);
353
    /// ```
354
    #[inline]
355
333k
    pub const fn year(self) -> i32 {
356
333k
        self.value.get() >> 10
357
333k
    }
<time::date::Date>::year
Line
Count
Source
355
333k
    pub const fn year(self) -> i32 {
356
333k
        self.value.get() >> 10
357
333k
    }
Unexecuted instantiation: <time::date::Date>::year
358
359
    /// Get the month.
360
    ///
361
    /// ```rust
362
    /// # use time::Month;
363
    /// # use time_macros::date;
364
    /// assert_eq!(date!(2019-01-01).month(), Month::January);
365
    /// assert_eq!(date!(2019-12-31).month(), Month::December);
366
    /// ```
367
    #[inline]
368
83.4k
    pub const fn month(self) -> Month {
369
83.4k
        let ordinal = self.ordinal() as u32;
370
83.4k
        let jan_feb_len = 59 + self.is_in_leap_year() as u32;
371
372
83.4k
        let (month_adj, ordinal_adj) = if ordinal <= jan_feb_len {
373
83.4k
            (0, 0)
374
        } else {
375
0
            (2, jan_feb_len)
376
        };
377
378
83.4k
        let ordinal = ordinal - ordinal_adj;
379
83.4k
        let month = ((ordinal * 268 + 8031) >> 13) + month_adj;
380
381
        // Safety: `month` is guaranteed to be between 1 and 12 inclusive.
382
        unsafe {
383
83.4k
            match Month::from_number(NonZero::new_unchecked(month as u8)) {
384
83.4k
                Ok(month) => month,
385
0
                Err(_) => core::hint::unreachable_unchecked(),
386
            }
387
        }
388
83.4k
    }
<time::date::Date>::month
Line
Count
Source
368
83.4k
    pub const fn month(self) -> Month {
369
83.4k
        let ordinal = self.ordinal() as u32;
370
83.4k
        let jan_feb_len = 59 + self.is_in_leap_year() as u32;
371
372
83.4k
        let (month_adj, ordinal_adj) = if ordinal <= jan_feb_len {
373
83.4k
            (0, 0)
374
        } else {
375
0
            (2, jan_feb_len)
376
        };
377
378
83.4k
        let ordinal = ordinal - ordinal_adj;
379
83.4k
        let month = ((ordinal * 268 + 8031) >> 13) + month_adj;
380
381
        // Safety: `month` is guaranteed to be between 1 and 12 inclusive.
382
        unsafe {
383
83.4k
            match Month::from_number(NonZero::new_unchecked(month as u8)) {
384
83.4k
                Ok(month) => month,
385
0
                Err(_) => core::hint::unreachable_unchecked(),
386
            }
387
        }
388
83.4k
    }
Unexecuted instantiation: <time::date::Date>::month
389
390
    /// Get the day of the month.
391
    ///
392
    /// The returned value will always be in the range `1..=31`.
393
    ///
394
    /// ```rust
395
    /// # use time_macros::date;
396
    /// assert_eq!(date!(2019-01-01).day(), 1);
397
    /// assert_eq!(date!(2019-12-31).day(), 31);
398
    /// ```
399
    #[inline]
400
83.4k
    pub const fn day(self) -> u8 {
401
83.4k
        let ordinal = self.ordinal() as u32;
402
83.4k
        let jan_feb_len = 59 + self.is_in_leap_year() as u32;
403
404
83.4k
        let ordinal_adj = if ordinal <= jan_feb_len {
405
83.4k
            0
406
        } else {
407
0
            jan_feb_len
408
        };
409
410
83.4k
        let ordinal = ordinal - ordinal_adj;
411
83.4k
        let month = (ordinal * 268 + 8031) >> 13;
412
83.4k
        let days_in_preceding_months = (month * 3917 - 3866) >> 7;
413
83.4k
        (ordinal - days_in_preceding_months) as u8
414
83.4k
    }
<time::date::Date>::day
Line
Count
Source
400
83.4k
    pub const fn day(self) -> u8 {
401
83.4k
        let ordinal = self.ordinal() as u32;
402
83.4k
        let jan_feb_len = 59 + self.is_in_leap_year() as u32;
403
404
83.4k
        let ordinal_adj = if ordinal <= jan_feb_len {
405
83.4k
            0
406
        } else {
407
0
            jan_feb_len
408
        };
409
410
83.4k
        let ordinal = ordinal - ordinal_adj;
411
83.4k
        let month = (ordinal * 268 + 8031) >> 13;
412
83.4k
        let days_in_preceding_months = (month * 3917 - 3866) >> 7;
413
83.4k
        (ordinal - days_in_preceding_months) as u8
414
83.4k
    }
Unexecuted instantiation: <time::date::Date>::day
415
416
    /// Get the day of the year.
417
    ///
418
    /// The returned value will always be in the range `1..=366` (`1..=365` for common years).
419
    ///
420
    /// ```rust
421
    /// # use time_macros::date;
422
    /// assert_eq!(date!(2019-01-01).ordinal(), 1);
423
    /// assert_eq!(date!(2019-12-31).ordinal(), 365);
424
    /// ```
425
    #[inline]
426
250k
    pub const fn ordinal(self) -> u16 {
427
250k
        (self.value.get() & 0x1FF) as u16
428
250k
    }
<time::date::Date>::ordinal
Line
Count
Source
426
250k
    pub const fn ordinal(self) -> u16 {
427
250k
        (self.value.get() & 0x1FF) as u16
428
250k
    }
Unexecuted instantiation: <time::date::Date>::ordinal
429
430
    /// Get the ISO 8601 year and week number.
431
    #[inline]
432
0
    pub(crate) const fn iso_year_week(self) -> (i32, u8) {
433
0
        let (year, ordinal) = self.to_ordinal_date();
434
435
0
        match ((ordinal + 10 - self.weekday().number_from_monday() as u16) / 7) as u8 {
436
0
            0 => (year - 1, weeks_in_year(year - 1)),
437
0
            53 if weeks_in_year(year) == 52 => (year + 1, 1),
438
0
            week => (year, week),
439
        }
440
0
    }
441
442
    /// Get the ISO week number.
443
    ///
444
    /// The returned value will always be in the range `1..=53`.
445
    ///
446
    /// ```rust
447
    /// # use time_macros::date;
448
    /// assert_eq!(date!(2019-01-01).iso_week(), 1);
449
    /// assert_eq!(date!(2019-10-04).iso_week(), 40);
450
    /// assert_eq!(date!(2020-01-01).iso_week(), 1);
451
    /// assert_eq!(date!(2020-12-31).iso_week(), 53);
452
    /// assert_eq!(date!(2021-01-01).iso_week(), 53);
453
    /// ```
454
    #[inline]
455
0
    pub const fn iso_week(self) -> u8 {
456
0
        self.iso_year_week().1
457
0
    }
458
459
    /// Get the week number where week 1 begins on the first Sunday.
460
    ///
461
    /// The returned value will always be in the range `0..=53`.
462
    ///
463
    /// ```rust
464
    /// # use time_macros::date;
465
    /// assert_eq!(date!(2019-01-01).sunday_based_week(), 0);
466
    /// assert_eq!(date!(2020-01-01).sunday_based_week(), 0);
467
    /// assert_eq!(date!(2020-12-31).sunday_based_week(), 52);
468
    /// assert_eq!(date!(2021-01-01).sunday_based_week(), 0);
469
    /// ```
470
    #[inline]
471
0
    pub const fn sunday_based_week(self) -> u8 {
472
0
        ((self.ordinal() as i16 - self.weekday().number_days_from_sunday() as i16 + 6) / 7) as u8
473
0
    }
474
475
    /// Get the week number where week 1 begins on the first Monday.
476
    ///
477
    /// The returned value will always be in the range `0..=53`.
478
    ///
479
    /// ```rust
480
    /// # use time_macros::date;
481
    /// assert_eq!(date!(2019-01-01).monday_based_week(), 0);
482
    /// assert_eq!(date!(2020-01-01).monday_based_week(), 0);
483
    /// assert_eq!(date!(2020-12-31).monday_based_week(), 52);
484
    /// assert_eq!(date!(2021-01-01).monday_based_week(), 0);
485
    /// ```
486
    #[inline]
487
0
    pub const fn monday_based_week(self) -> u8 {
488
0
        ((self.ordinal() as i16 - self.weekday().number_days_from_monday() as i16 + 6) / 7) as u8
489
0
    }
490
491
    /// Get the year, month, and day.
492
    ///
493
    /// ```rust
494
    /// # use time::Month;
495
    /// # use time_macros::date;
496
    /// assert_eq!(
497
    ///     date!(2019-01-01).to_calendar_date(),
498
    ///     (2019, Month::January, 1)
499
    /// );
500
    /// ```
501
    #[inline]
502
0
    pub const fn to_calendar_date(self) -> (i32, Month, u8) {
503
0
        let (year, ordinal) = self.to_ordinal_date();
504
0
        let ordinal = ordinal as u32;
505
0
        let jan_feb_len = 59 + self.is_in_leap_year() as u32;
506
507
0
        let (month_adj, ordinal_adj) = if ordinal <= jan_feb_len {
508
0
            (0, 0)
509
        } else {
510
0
            (2, jan_feb_len)
511
        };
512
513
0
        let ordinal = ordinal - ordinal_adj;
514
0
        let month = (ordinal * 268 + 8031) >> 13;
515
0
        let days_in_preceding_months = (month * 3917 - 3866) >> 7;
516
0
        let day = ordinal - days_in_preceding_months;
517
0
        let month = month + month_adj;
518
519
        (
520
0
            year,
521
            // Safety: `month` is guaranteed to be between 1 and 12 inclusive.
522
            unsafe {
523
0
                match Month::from_number(NonZero::new_unchecked(month as u8)) {
524
0
                    Ok(month) => month,
525
0
                    Err(_) => core::hint::unreachable_unchecked(),
526
                }
527
            },
528
0
            day as u8,
529
        )
530
0
    }
531
532
    /// Get the year and ordinal day number.
533
    ///
534
    /// ```rust
535
    /// # use time_macros::date;
536
    /// assert_eq!(date!(2019-01-01).to_ordinal_date(), (2019, 1));
537
    /// ```
538
    #[inline]
539
83.4k
    pub const fn to_ordinal_date(self) -> (i32, u16) {
540
83.4k
        (self.year(), self.ordinal())
541
83.4k
    }
<time::date::Date>::to_ordinal_date
Line
Count
Source
539
83.4k
    pub const fn to_ordinal_date(self) -> (i32, u16) {
540
83.4k
        (self.year(), self.ordinal())
541
83.4k
    }
Unexecuted instantiation: <time::date::Date>::to_ordinal_date
542
543
    /// Get the ISO 8601 year, week number, and weekday.
544
    ///
545
    /// ```rust
546
    /// # use time::Weekday::*;
547
    /// # use time_macros::date;
548
    /// assert_eq!(date!(2019-01-01).to_iso_week_date(), (2019, 1, Tuesday));
549
    /// assert_eq!(date!(2019-10-04).to_iso_week_date(), (2019, 40, Friday));
550
    /// assert_eq!(date!(2020-01-01).to_iso_week_date(), (2020, 1, Wednesday));
551
    /// assert_eq!(date!(2020-12-31).to_iso_week_date(), (2020, 53, Thursday));
552
    /// assert_eq!(date!(2021-01-01).to_iso_week_date(), (2020, 53, Friday));
553
    /// ```
554
    #[inline]
555
0
    pub const fn to_iso_week_date(self) -> (i32, u8, Weekday) {
556
0
        let (year, ordinal) = self.to_ordinal_date();
557
0
        let weekday = self.weekday();
558
559
0
        match ((ordinal + 10 - weekday.number_from_monday() as u16) / 7) as u8 {
560
0
            0 => (year - 1, weeks_in_year(year - 1), weekday),
561
0
            53 if weeks_in_year(year) == 52 => (year + 1, 1, weekday),
562
0
            week => (year, week, weekday),
563
        }
564
0
    }
565
566
    /// Get the weekday.
567
    ///
568
    /// ```rust
569
    /// # use time::Weekday::*;
570
    /// # use time_macros::date;
571
    /// assert_eq!(date!(2019-01-01).weekday(), Tuesday);
572
    /// assert_eq!(date!(2019-02-01).weekday(), Friday);
573
    /// assert_eq!(date!(2019-03-01).weekday(), Friday);
574
    /// assert_eq!(date!(2019-04-01).weekday(), Monday);
575
    /// assert_eq!(date!(2019-05-01).weekday(), Wednesday);
576
    /// assert_eq!(date!(2019-06-01).weekday(), Saturday);
577
    /// assert_eq!(date!(2019-07-01).weekday(), Monday);
578
    /// assert_eq!(date!(2019-08-01).weekday(), Thursday);
579
    /// assert_eq!(date!(2019-09-01).weekday(), Sunday);
580
    /// assert_eq!(date!(2019-10-01).weekday(), Tuesday);
581
    /// assert_eq!(date!(2019-11-01).weekday(), Friday);
582
    /// assert_eq!(date!(2019-12-01).weekday(), Sunday);
583
    /// ```
584
    #[inline]
585
0
    pub const fn weekday(self) -> Weekday {
586
0
        match self.to_julian_day() % 7 {
587
0
            -6 | 1 => Weekday::Tuesday,
588
0
            -5 | 2 => Weekday::Wednesday,
589
0
            -4 | 3 => Weekday::Thursday,
590
0
            -3 | 4 => Weekday::Friday,
591
0
            -2 | 5 => Weekday::Saturday,
592
0
            -1 | 6 => Weekday::Sunday,
593
0
            val => {
594
0
                debug_assert!(val == 0);
595
0
                Weekday::Monday
596
            }
597
        }
598
0
    }
599
600
    /// Get the next calendar date.
601
    ///
602
    /// ```rust
603
    /// # use time::Date;
604
    /// # use time_macros::date;
605
    /// assert_eq!(date!(2019-01-01).next_day(), Some(date!(2019-01-02)));
606
    /// assert_eq!(date!(2019-01-31).next_day(), Some(date!(2019-02-01)));
607
    /// assert_eq!(date!(2019-12-31).next_day(), Some(date!(2020-01-01)));
608
    /// assert_eq!(Date::MAX.next_day(), None);
609
    /// ```
610
    #[inline]
611
0
    pub const fn next_day(self) -> Option<Self> {
612
0
        if self.ordinal() == 366 || (self.ordinal() == 365 && !self.is_in_leap_year()) {
613
0
            if self.value.get() == Self::MAX.value.get() {
614
0
                None
615
            } else {
616
                // Safety: `ordinal` is not zero.
617
0
                unsafe { Some(Self::__from_ordinal_date_unchecked(self.year() + 1, 1)) }
618
            }
619
        } else {
620
0
            Some(Self {
621
0
                // Safety: `ordinal` is not zero.
622
0
                value: unsafe { NonZero::new_unchecked(self.value.get() + 1) },
623
0
            })
624
        }
625
0
    }
Unexecuted instantiation: <time::date::Date>::next_day
Unexecuted instantiation: <time::date::Date>::next_day
626
627
    /// Get the previous calendar date.
628
    ///
629
    /// ```rust
630
    /// # use time::Date;
631
    /// # use time_macros::date;
632
    /// assert_eq!(date!(2019-01-02).previous_day(), Some(date!(2019-01-01)));
633
    /// assert_eq!(date!(2019-02-01).previous_day(), Some(date!(2019-01-31)));
634
    /// assert_eq!(date!(2020-01-01).previous_day(), Some(date!(2019-12-31)));
635
    /// assert_eq!(Date::MIN.previous_day(), None);
636
    /// ```
637
    #[inline]
638
0
    pub const fn previous_day(self) -> Option<Self> {
639
0
        if self.ordinal() != 1 {
640
0
            Some(Self {
641
0
                // Safety: `ordinal` is not zero.
642
0
                value: unsafe { NonZero::new_unchecked(self.value.get() - 1) },
643
0
            })
644
0
        } else if self.value.get() == Self::MIN.value.get() {
645
0
            None
646
        } else {
647
            // Safety: `ordinal` is not zero.
648
0
            Some(unsafe {
649
0
                Self::__from_ordinal_date_unchecked(self.year() - 1, days_in_year(self.year() - 1))
650
0
            })
651
        }
652
0
    }
Unexecuted instantiation: <time::date::Date>::previous_day
Unexecuted instantiation: <time::date::Date>::previous_day
653
654
    /// Calculates the first occurrence of a weekday that is strictly later than a given `Date`.
655
    ///
656
    /// # Panics
657
    /// Panics if an overflow occurred.
658
    ///
659
    /// # Examples
660
    /// ```
661
    /// # use time::Weekday;
662
    /// # use time_macros::date;
663
    /// assert_eq!(
664
    ///     date!(2023-06-28).next_occurrence(Weekday::Monday),
665
    ///     date!(2023-07-03)
666
    /// );
667
    /// assert_eq!(
668
    ///     date!(2023-06-19).next_occurrence(Weekday::Monday),
669
    ///     date!(2023-06-26)
670
    /// );
671
    /// ```
672
    #[inline]
673
    #[track_caller]
674
0
    pub const fn next_occurrence(self, weekday: Weekday) -> Self {
675
0
        self.checked_next_occurrence(weekday)
676
0
            .expect("overflow calculating the next occurrence of a weekday")
677
0
    }
678
679
    /// Calculates the first occurrence of a weekday that is strictly earlier than a given `Date`.
680
    ///
681
    /// # Panics
682
    /// Panics if an overflow occurred.
683
    ///
684
    /// # Examples
685
    /// ```
686
    /// # use time::Weekday;
687
    /// # use time_macros::date;
688
    /// assert_eq!(
689
    ///     date!(2023-06-28).prev_occurrence(Weekday::Monday),
690
    ///     date!(2023-06-26)
691
    /// );
692
    /// assert_eq!(
693
    ///     date!(2023-06-19).prev_occurrence(Weekday::Monday),
694
    ///     date!(2023-06-12)
695
    /// );
696
    /// ```
697
    #[inline]
698
    #[track_caller]
699
0
    pub const fn prev_occurrence(self, weekday: Weekday) -> Self {
700
0
        self.checked_prev_occurrence(weekday)
701
0
            .expect("overflow calculating the previous occurrence of a weekday")
702
0
    }
703
704
    /// Calculates the `n`th occurrence of a weekday that is strictly later than a given `Date`.
705
    ///
706
    /// # Panics
707
    /// Panics if an overflow occurred or if `n == 0`.
708
    ///
709
    /// # Examples
710
    /// ```
711
    /// # use time::Weekday;
712
    /// # use time_macros::date;
713
    /// assert_eq!(
714
    ///     date!(2023-06-25).nth_next_occurrence(Weekday::Monday, 5),
715
    ///     date!(2023-07-24)
716
    /// );
717
    /// assert_eq!(
718
    ///     date!(2023-06-26).nth_next_occurrence(Weekday::Monday, 5),
719
    ///     date!(2023-07-31)
720
    /// );
721
    /// ```
722
    #[inline]
723
    #[track_caller]
724
0
    pub const fn nth_next_occurrence(self, weekday: Weekday, n: u8) -> Self {
725
0
        self.checked_nth_next_occurrence(weekday, n)
726
0
            .expect("overflow calculating the next occurrence of a weekday")
727
0
    }
728
729
    /// Calculates the `n`th occurrence of a weekday that is strictly earlier than a given `Date`.
730
    ///
731
    /// # Panics
732
    /// Panics if an overflow occurred or if `n == 0`.
733
    ///
734
    /// # Examples
735
    /// ```
736
    /// # use time::Weekday;
737
    /// # use time_macros::date;
738
    /// assert_eq!(
739
    ///     date!(2023-06-27).nth_prev_occurrence(Weekday::Monday, 3),
740
    ///     date!(2023-06-12)
741
    /// );
742
    /// assert_eq!(
743
    ///     date!(2023-06-26).nth_prev_occurrence(Weekday::Monday, 3),
744
    ///     date!(2023-06-05)
745
    /// );
746
    /// ```
747
    #[inline]
748
    #[track_caller]
749
0
    pub const fn nth_prev_occurrence(self, weekday: Weekday, n: u8) -> Self {
750
0
        self.checked_nth_prev_occurrence(weekday, n)
751
0
            .expect("overflow calculating the previous occurrence of a weekday")
752
0
    }
753
754
    /// Get the Julian day for the date.
755
    ///
756
    /// ```rust
757
    /// # use time_macros::date;
758
    /// assert_eq!(date!(-4713 - 11 - 24).to_julian_day(), 0);
759
    /// assert_eq!(date!(2000-01-01).to_julian_day(), 2_451_545);
760
    /// assert_eq!(date!(2019-01-01).to_julian_day(), 2_458_485);
761
    /// assert_eq!(date!(2019-12-31).to_julian_day(), 2_458_849);
762
    /// ```
763
    #[inline]
764
83.4k
    pub const fn to_julian_day(self) -> i32 {
765
83.4k
        let (year, ordinal) = self.to_ordinal_date();
766
767
        // The algorithm requires a non-negative year. Add the lowest value to make it so. This is
768
        // adjusted for at the end with the final subtraction.
769
83.4k
        let adj_year = year + 999_999;
770
83.4k
        let century = adj_year / 100;
771
772
83.4k
        let days_before_year = (1461 * adj_year as i64 / 4) as i32 - century + century / 4;
773
83.4k
        days_before_year + ordinal as i32 - 363_521_075
774
83.4k
    }
<time::date::Date>::to_julian_day
Line
Count
Source
764
83.4k
    pub const fn to_julian_day(self) -> i32 {
765
83.4k
        let (year, ordinal) = self.to_ordinal_date();
766
767
        // The algorithm requires a non-negative year. Add the lowest value to make it so. This is
768
        // adjusted for at the end with the final subtraction.
769
83.4k
        let adj_year = year + 999_999;
770
83.4k
        let century = adj_year / 100;
771
772
83.4k
        let days_before_year = (1461 * adj_year as i64 / 4) as i32 - century + century / 4;
773
83.4k
        days_before_year + ordinal as i32 - 363_521_075
774
83.4k
    }
Unexecuted instantiation: <time::date::Date>::to_julian_day
775
776
    /// Computes `self + duration`, returning `None` if an overflow occurred.
777
    ///
778
    /// ```rust
779
    /// # use time::{Date, ext::NumericalDuration};
780
    /// # use time_macros::date;
781
    /// assert_eq!(Date::MAX.checked_add(1.days()), None);
782
    /// assert_eq!(Date::MIN.checked_add((-2).days()), None);
783
    /// assert_eq!(
784
    ///     date!(2020-12-31).checked_add(2.days()),
785
    ///     Some(date!(2021-01-02))
786
    /// );
787
    /// ```
788
    ///
789
    /// # Note
790
    ///
791
    /// This function only takes whole days into account.
792
    ///
793
    /// ```rust
794
    /// # use time::{Date, ext::NumericalDuration};
795
    /// # use time_macros::date;
796
    /// assert_eq!(Date::MAX.checked_add(23.hours()), Some(Date::MAX));
797
    /// assert_eq!(Date::MIN.checked_add((-23).hours()), Some(Date::MIN));
798
    /// assert_eq!(
799
    ///     date!(2020-12-31).checked_add(23.hours()),
800
    ///     Some(date!(2020-12-31))
801
    /// );
802
    /// assert_eq!(
803
    ///     date!(2020-12-31).checked_add(47.hours()),
804
    ///     Some(date!(2021-01-01))
805
    /// );
806
    /// ```
807
    #[inline]
808
0
    pub const fn checked_add(self, duration: Duration) -> Option<Self> {
809
0
        let whole_days = duration.whole_days();
810
0
        if whole_days < i32::MIN as i64 || whole_days > i32::MAX as i64 {
811
0
            return None;
812
0
        }
813
814
0
        let julian_day = const_try_opt!(self.to_julian_day().checked_add(whole_days as i32));
815
0
        if let Ok(date) = Self::from_julian_day(julian_day) {
816
0
            Some(date)
817
        } else {
818
0
            None
819
        }
820
0
    }
821
822
    /// Computes `self + duration`, returning `None` if an overflow occurred.
823
    ///
824
    /// ```rust
825
    /// # use time::{Date, ext::NumericalStdDuration};
826
    /// # use time_macros::date;
827
    /// assert_eq!(Date::MAX.checked_add_std(1.std_days()), None);
828
    /// assert_eq!(
829
    ///     date!(2020-12-31).checked_add_std(2.std_days()),
830
    ///     Some(date!(2021-01-02))
831
    /// );
832
    /// ```
833
    ///
834
    /// # Note
835
    ///
836
    /// This function only takes whole days into account.
837
    ///
838
    /// ```rust
839
    /// # use time::{Date, ext::NumericalStdDuration};
840
    /// # use time_macros::date;
841
    /// assert_eq!(Date::MAX.checked_add_std(23.std_hours()), Some(Date::MAX));
842
    /// assert_eq!(
843
    ///     date!(2020-12-31).checked_add_std(23.std_hours()),
844
    ///     Some(date!(2020-12-31))
845
    /// );
846
    /// assert_eq!(
847
    ///     date!(2020-12-31).checked_add_std(47.std_hours()),
848
    ///     Some(date!(2021-01-01))
849
    /// );
850
    /// ```
851
    #[inline]
852
83.4k
    pub const fn checked_add_std(self, duration: StdDuration) -> Option<Self> {
853
83.4k
        let whole_days = duration.as_secs() / Second::per_t::<u64>(Day);
854
83.4k
        if whole_days > i32::MAX as u64 {
855
0
            return None;
856
83.4k
        }
857
858
83.4k
        let julian_day = const_try_opt!(self.to_julian_day().checked_add(whole_days as i32));
859
83.4k
        if let Ok(date) = Self::from_julian_day(julian_day) {
860
83.4k
            Some(date)
861
        } else {
862
0
            None
863
        }
864
83.4k
    }
<time::date::Date>::checked_add_std
Line
Count
Source
852
83.4k
    pub const fn checked_add_std(self, duration: StdDuration) -> Option<Self> {
853
83.4k
        let whole_days = duration.as_secs() / Second::per_t::<u64>(Day);
854
83.4k
        if whole_days > i32::MAX as u64 {
855
0
            return None;
856
83.4k
        }
857
858
83.4k
        let julian_day = const_try_opt!(self.to_julian_day().checked_add(whole_days as i32));
859
83.4k
        if let Ok(date) = Self::from_julian_day(julian_day) {
860
83.4k
            Some(date)
861
        } else {
862
0
            None
863
        }
864
83.4k
    }
Unexecuted instantiation: <time::date::Date>::checked_add_std
865
866
    /// Computes `self - duration`, returning `None` if an overflow occurred.
867
    ///
868
    /// ```
869
    /// # use time::{Date, ext::NumericalDuration};
870
    /// # use time_macros::date;
871
    /// assert_eq!(Date::MAX.checked_sub((-2).days()), None);
872
    /// assert_eq!(Date::MIN.checked_sub(1.days()), None);
873
    /// assert_eq!(
874
    ///     date!(2020-12-31).checked_sub(2.days()),
875
    ///     Some(date!(2020-12-29))
876
    /// );
877
    /// ```
878
    ///
879
    /// # Note
880
    ///
881
    /// This function only takes whole days into account.
882
    ///
883
    /// ```
884
    /// # use time::{Date, ext::NumericalDuration};
885
    /// # use time_macros::date;
886
    /// assert_eq!(Date::MAX.checked_sub((-23).hours()), Some(Date::MAX));
887
    /// assert_eq!(Date::MIN.checked_sub(23.hours()), Some(Date::MIN));
888
    /// assert_eq!(
889
    ///     date!(2020-12-31).checked_sub(23.hours()),
890
    ///     Some(date!(2020-12-31))
891
    /// );
892
    /// assert_eq!(
893
    ///     date!(2020-12-31).checked_sub(47.hours()),
894
    ///     Some(date!(2020-12-30))
895
    /// );
896
    /// ```
897
    #[inline]
898
0
    pub const fn checked_sub(self, duration: Duration) -> Option<Self> {
899
0
        let whole_days = duration.whole_days();
900
0
        if whole_days < i32::MIN as i64 || whole_days > i32::MAX as i64 {
901
0
            return None;
902
0
        }
903
904
0
        let julian_day = const_try_opt!(self.to_julian_day().checked_sub(whole_days as i32));
905
0
        if let Ok(date) = Self::from_julian_day(julian_day) {
906
0
            Some(date)
907
        } else {
908
0
            None
909
        }
910
0
    }
911
912
    /// Computes `self - duration`, returning `None` if an overflow occurred.
913
    ///
914
    /// ```
915
    /// # use time::{Date, ext::NumericalStdDuration};
916
    /// # use time_macros::date;
917
    /// assert_eq!(Date::MIN.checked_sub_std(1.std_days()), None);
918
    /// assert_eq!(
919
    ///     date!(2020-12-31).checked_sub_std(2.std_days()),
920
    ///     Some(date!(2020-12-29))
921
    /// );
922
    /// ```
923
    ///
924
    /// # Note
925
    ///
926
    /// This function only takes whole days into account.
927
    ///
928
    /// ```
929
    /// # use time::{Date, ext::NumericalStdDuration};
930
    /// # use time_macros::date;
931
    /// assert_eq!(Date::MIN.checked_sub_std(23.std_hours()), Some(Date::MIN));
932
    /// assert_eq!(
933
    ///     date!(2020-12-31).checked_sub_std(23.std_hours()),
934
    ///     Some(date!(2020-12-31))
935
    /// );
936
    /// assert_eq!(
937
    ///     date!(2020-12-31).checked_sub_std(47.std_hours()),
938
    ///     Some(date!(2020-12-30))
939
    /// );
940
    /// ```
941
    #[inline]
942
0
    pub const fn checked_sub_std(self, duration: StdDuration) -> Option<Self> {
943
0
        let whole_days = duration.as_secs() / Second::per_t::<u64>(Day);
944
0
        if whole_days > i32::MAX as u64 {
945
0
            return None;
946
0
        }
947
948
0
        let julian_day = const_try_opt!(self.to_julian_day().checked_sub(whole_days as i32));
949
0
        if let Ok(date) = Self::from_julian_day(julian_day) {
950
0
            Some(date)
951
        } else {
952
0
            None
953
        }
954
0
    }
Unexecuted instantiation: <time::date::Date>::checked_sub_std
Unexecuted instantiation: <time::date::Date>::checked_sub_std
955
956
    /// Calculates the first occurrence of a weekday that is strictly later than a given `Date`.
957
    /// Returns `None` if an overflow occurred.
958
    #[inline]
959
0
    pub(crate) const fn checked_next_occurrence(self, weekday: Weekday) -> Option<Self> {
960
0
        let day_diff = match weekday as i8 - self.weekday() as i8 {
961
0
            1 | -6 => 1,
962
0
            2 | -5 => 2,
963
0
            3 | -4 => 3,
964
0
            4 | -3 => 4,
965
0
            5 | -2 => 5,
966
0
            6 | -1 => 6,
967
0
            val => {
968
0
                debug_assert!(val == 0);
969
0
                7
970
            }
971
        };
972
973
0
        self.checked_add(Duration::days(day_diff))
974
0
    }
975
976
    /// Calculates the first occurrence of a weekday that is strictly earlier than a given `Date`.
977
    /// Returns `None` if an overflow occurred.
978
    #[inline]
979
0
    pub(crate) const fn checked_prev_occurrence(self, weekday: Weekday) -> Option<Self> {
980
0
        let day_diff = match weekday as i8 - self.weekday() as i8 {
981
0
            1 | -6 => 6,
982
0
            2 | -5 => 5,
983
0
            3 | -4 => 4,
984
0
            4 | -3 => 3,
985
0
            5 | -2 => 2,
986
0
            6 | -1 => 1,
987
0
            val => {
988
0
                debug_assert!(val == 0);
989
0
                7
990
            }
991
        };
992
993
0
        self.checked_sub(Duration::days(day_diff))
994
0
    }
995
996
    /// Calculates the `n`th occurrence of a weekday that is strictly later than a given `Date`.
997
    /// Returns `None` if an overflow occurred or if `n == 0`.
998
    #[inline]
999
0
    pub(crate) const fn checked_nth_next_occurrence(self, weekday: Weekday, n: u8) -> Option<Self> {
1000
0
        if n == 0 {
1001
0
            return None;
1002
0
        }
1003
1004
0
        const_try_opt!(self.checked_next_occurrence(weekday))
1005
0
            .checked_add(Duration::weeks(n as i64 - 1))
1006
0
    }
1007
1008
    /// Calculates the `n`th occurrence of a weekday that is strictly earlier than a given `Date`.
1009
    /// Returns `None` if an overflow occurred or if `n == 0`.
1010
    #[inline]
1011
0
    pub(crate) const fn checked_nth_prev_occurrence(self, weekday: Weekday, n: u8) -> Option<Self> {
1012
0
        if n == 0 {
1013
0
            return None;
1014
0
        }
1015
1016
0
        const_try_opt!(self.checked_prev_occurrence(weekday))
1017
0
            .checked_sub(Duration::weeks(n as i64 - 1))
1018
0
    }
1019
1020
    /// Computes `self + duration`, saturating value on overflow.
1021
    ///
1022
    /// ```rust
1023
    /// # use time::{Date, ext::NumericalDuration};
1024
    /// # use time_macros::date;
1025
    /// assert_eq!(Date::MAX.saturating_add(1.days()), Date::MAX);
1026
    /// assert_eq!(Date::MIN.saturating_add((-2).days()), Date::MIN);
1027
    /// assert_eq!(
1028
    ///     date!(2020-12-31).saturating_add(2.days()),
1029
    ///     date!(2021-01-02)
1030
    /// );
1031
    /// ```
1032
    ///
1033
    /// # Note
1034
    ///
1035
    /// This function only takes whole days into account.
1036
    ///
1037
    /// ```rust
1038
    /// # use time::ext::NumericalDuration;
1039
    /// # use time_macros::date;
1040
    /// assert_eq!(
1041
    ///     date!(2020-12-31).saturating_add(23.hours()),
1042
    ///     date!(2020-12-31)
1043
    /// );
1044
    /// assert_eq!(
1045
    ///     date!(2020-12-31).saturating_add(47.hours()),
1046
    ///     date!(2021-01-01)
1047
    /// );
1048
    /// ```
1049
    #[inline]
1050
0
    pub const fn saturating_add(self, duration: Duration) -> Self {
1051
0
        if let Some(datetime) = self.checked_add(duration) {
1052
0
            datetime
1053
0
        } else if duration.is_negative() {
1054
0
            Self::MIN
1055
        } else {
1056
0
            debug_assert!(duration.is_positive());
1057
0
            Self::MAX
1058
        }
1059
0
    }
1060
1061
    /// Computes `self - duration`, saturating value on overflow.
1062
    ///
1063
    /// ```
1064
    /// # use time::{Date, ext::NumericalDuration};
1065
    /// # use time_macros::date;
1066
    /// assert_eq!(Date::MAX.saturating_sub((-2).days()), Date::MAX);
1067
    /// assert_eq!(Date::MIN.saturating_sub(1.days()), Date::MIN);
1068
    /// assert_eq!(
1069
    ///     date!(2020-12-31).saturating_sub(2.days()),
1070
    ///     date!(2020-12-29)
1071
    /// );
1072
    /// ```
1073
    ///
1074
    /// # Note
1075
    ///
1076
    /// This function only takes whole days into account.
1077
    ///
1078
    /// ```
1079
    /// # use time::ext::NumericalDuration;
1080
    /// # use time_macros::date;
1081
    /// assert_eq!(
1082
    ///     date!(2020-12-31).saturating_sub(23.hours()),
1083
    ///     date!(2020-12-31)
1084
    /// );
1085
    /// assert_eq!(
1086
    ///     date!(2020-12-31).saturating_sub(47.hours()),
1087
    ///     date!(2020-12-30)
1088
    /// );
1089
    /// ```
1090
    #[inline]
1091
0
    pub const fn saturating_sub(self, duration: Duration) -> Self {
1092
0
        if let Some(datetime) = self.checked_sub(duration) {
1093
0
            datetime
1094
0
        } else if duration.is_negative() {
1095
0
            Self::MAX
1096
        } else {
1097
0
            debug_assert!(duration.is_positive());
1098
0
            Self::MIN
1099
        }
1100
0
    }
1101
1102
    /// Replace the year. The month and day will be unchanged.
1103
    ///
1104
    /// ```rust
1105
    /// # use time_macros::date;
1106
    /// assert_eq!(
1107
    ///     date!(2022-02-18).replace_year(2019),
1108
    ///     Ok(date!(2019-02-18))
1109
    /// );
1110
    /// assert!(date!(2022-02-18).replace_year(-1_000_000_000).is_err()); // -1_000_000_000 isn't a valid year
1111
    /// assert!(date!(2022-02-18).replace_year(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid year
1112
    /// ```
1113
    #[inline]
1114
    #[must_use = "This method does not mutate the original `Date`."]
1115
0
    pub const fn replace_year(self, year: i32) -> Result<Self, error::ComponentRange> {
1116
0
        ensure_ranged!(Year: year);
1117
1118
0
        let ordinal = self.ordinal();
1119
1120
        // Dates in January and February are unaffected by leap years.
1121
0
        if ordinal <= 59 {
1122
            // Safety: `ordinal` is not zero.
1123
0
            return Ok(unsafe { Self::__from_ordinal_date_unchecked(year, ordinal) });
1124
0
        }
1125
1126
0
        match (self.is_in_leap_year(), is_leap_year(year)) {
1127
            (false, false) | (true, true) => {
1128
                // Safety: `ordinal` is not zero.
1129
0
                Ok(unsafe { Self::__from_ordinal_date_unchecked(year, ordinal) })
1130
            }
1131
            // February 29 does not exist in common years.
1132
0
            (true, false) if ordinal == 60 => Err(error::ComponentRange {
1133
0
                name: "day",
1134
0
                value: 29,
1135
0
                minimum: 1,
1136
0
                maximum: 28,
1137
0
                conditional_message: Some("for the given month and year"),
1138
0
            }),
1139
            // We're going from a common year to a leap year. Shift dates in March and later by
1140
            // one day.
1141
            // Safety: `ordinal` is not zero.
1142
0
            (false, true) => Ok(unsafe { Self::__from_ordinal_date_unchecked(year, ordinal + 1) }),
1143
            // We're going from a leap year to a common year. Shift dates in January and
1144
            // February by one day.
1145
            // Safety: `ordinal` is not zero.
1146
0
            (true, false) => Ok(unsafe { Self::__from_ordinal_date_unchecked(year, ordinal - 1) }),
1147
        }
1148
0
    }
1149
1150
    /// Replace the month of the year.
1151
    ///
1152
    /// ```rust
1153
    /// # use time_macros::date;
1154
    /// # use time::Month;
1155
    /// assert_eq!(
1156
    ///     date!(2022-02-18).replace_month(Month::January),
1157
    ///     Ok(date!(2022-01-18))
1158
    /// );
1159
    /// assert!(date!(2022-01-30)
1160
    ///     .replace_month(Month::February)
1161
    ///     .is_err()); // 30 isn't a valid day in February
1162
    /// ```
1163
    #[inline]
1164
    #[must_use = "This method does not mutate the original `Date`."]
1165
0
    pub const fn replace_month(self, month: Month) -> Result<Self, error::ComponentRange> {
1166
0
        let (year, _, day) = self.to_calendar_date();
1167
0
        Self::from_calendar_date(year, month, day)
1168
0
    }
1169
1170
    /// Replace the day of the month.
1171
    ///
1172
    /// ```rust
1173
    /// # use time_macros::date;
1174
    /// assert_eq!(date!(2022-02-18).replace_day(1), Ok(date!(2022-02-01)));
1175
    /// assert!(date!(2022-02-18).replace_day(0).is_err()); // 0 isn't a valid day
1176
    /// assert!(date!(2022-02-18).replace_day(30).is_err()); // 30 isn't a valid day in February
1177
    /// ```
1178
    #[inline]
1179
    #[must_use = "This method does not mutate the original `Date`."]
1180
0
    pub const fn replace_day(self, day: u8) -> Result<Self, error::ComponentRange> {
1181
0
        match day {
1182
0
            1..=28 => {}
1183
0
            29..=31 if day <= self.month().length(self.year()) => {}
1184
            _ => {
1185
0
                return Err(error::ComponentRange {
1186
0
                    name: "day",
1187
0
                    minimum: 1,
1188
0
                    maximum: self.month().length(self.year()) as i64,
1189
0
                    value: day as i64,
1190
0
                    conditional_message: Some("for the given month and year"),
1191
0
                });
1192
            }
1193
        }
1194
1195
        // Safety: `ordinal` is not zero.
1196
0
        Ok(unsafe {
1197
0
            Self::__from_ordinal_date_unchecked(
1198
0
                self.year(),
1199
0
                (self.ordinal() as i16 - self.day() as i16 + day as i16) as u16,
1200
0
            )
1201
0
        })
1202
0
    }
1203
1204
    /// Replace the day of the year.
1205
    ///
1206
    /// ```rust
1207
    /// # use time_macros::date;
1208
    /// assert_eq!(date!(2022-049).replace_ordinal(1), Ok(date!(2022-001)));
1209
    /// assert!(date!(2022-049).replace_ordinal(0).is_err()); // 0 isn't a valid ordinal
1210
    /// assert!(date!(2022-049).replace_ordinal(366).is_err()); // 2022 isn't a leap year
1211
    /// ````
1212
    #[inline]
1213
    #[must_use = "This method does not mutate the original `Date`."]
1214
0
    pub const fn replace_ordinal(self, ordinal: u16) -> Result<Self, error::ComponentRange> {
1215
0
        match ordinal {
1216
0
            1..=365 => {}
1217
0
            366 if self.is_in_leap_year() => {}
1218
            _ => {
1219
0
                return Err(error::ComponentRange {
1220
0
                    name: "ordinal",
1221
0
                    minimum: 1,
1222
0
                    maximum: days_in_year(self.year()) as i64,
1223
0
                    value: ordinal as i64,
1224
0
                    conditional_message: Some("for the given year"),
1225
0
                });
1226
            }
1227
        }
1228
1229
        // Safety: `ordinal` is in range.
1230
0
        Ok(unsafe { Self::__from_ordinal_date_unchecked(self.year(), ordinal) })
1231
0
    }
1232
}
1233
1234
/// Methods to add a [`Time`] component, resulting in a [`PrimitiveDateTime`].
1235
impl Date {
1236
    /// Create a [`PrimitiveDateTime`] using the existing date. The [`Time`] component will be set
1237
    /// to midnight.
1238
    ///
1239
    /// ```rust
1240
    /// # use time_macros::{date, datetime};
1241
    /// assert_eq!(date!(1970-01-01).midnight(), datetime!(1970-01-01 0:00));
1242
    /// ```
1243
    #[inline]
1244
0
    pub const fn midnight(self) -> PrimitiveDateTime {
1245
0
        PrimitiveDateTime::new(self, Time::MIDNIGHT)
1246
0
    }
1247
1248
    /// Create a [`PrimitiveDateTime`] using the existing date and the provided [`Time`].
1249
    ///
1250
    /// ```rust
1251
    /// # use time_macros::{date, datetime, time};
1252
    /// assert_eq!(
1253
    ///     date!(1970-01-01).with_time(time!(0:00)),
1254
    ///     datetime!(1970-01-01 0:00),
1255
    /// );
1256
    /// ```
1257
    #[inline]
1258
83.4k
    pub const fn with_time(self, time: Time) -> PrimitiveDateTime {
1259
83.4k
        PrimitiveDateTime::new(self, time)
1260
83.4k
    }
<time::date::Date>::with_time
Line
Count
Source
1258
83.4k
    pub const fn with_time(self, time: Time) -> PrimitiveDateTime {
1259
83.4k
        PrimitiveDateTime::new(self, time)
1260
83.4k
    }
Unexecuted instantiation: <time::date::Date>::with_time
1261
1262
    /// Attempt to create a [`PrimitiveDateTime`] using the existing date and the provided time.
1263
    ///
1264
    /// ```rust
1265
    /// # use time_macros::date;
1266
    /// assert!(date!(1970-01-01).with_hms(0, 0, 0).is_ok());
1267
    /// assert!(date!(1970-01-01).with_hms(24, 0, 0).is_err());
1268
    /// ```
1269
    #[inline]
1270
0
    pub const fn with_hms(
1271
0
        self,
1272
0
        hour: u8,
1273
0
        minute: u8,
1274
0
        second: u8,
1275
0
    ) -> Result<PrimitiveDateTime, error::ComponentRange> {
1276
0
        Ok(PrimitiveDateTime::new(
1277
0
            self,
1278
0
            const_try!(Time::from_hms(hour, minute, second)),
1279
        ))
1280
0
    }
1281
1282
    /// Attempt to create a [`PrimitiveDateTime`] using the existing date and the provided time.
1283
    ///
1284
    /// ```rust
1285
    /// # use time_macros::date;
1286
    /// assert!(date!(1970-01-01).with_hms_milli(0, 0, 0, 0).is_ok());
1287
    /// assert!(date!(1970-01-01).with_hms_milli(24, 0, 0, 0).is_err());
1288
    /// ```
1289
    #[inline]
1290
0
    pub const fn with_hms_milli(
1291
0
        self,
1292
0
        hour: u8,
1293
0
        minute: u8,
1294
0
        second: u8,
1295
0
        millisecond: u16,
1296
0
    ) -> Result<PrimitiveDateTime, error::ComponentRange> {
1297
0
        Ok(PrimitiveDateTime::new(
1298
0
            self,
1299
0
            const_try!(Time::from_hms_milli(hour, minute, second, millisecond)),
1300
        ))
1301
0
    }
1302
1303
    /// Attempt to create a [`PrimitiveDateTime`] using the existing date and the provided time.
1304
    ///
1305
    /// ```rust
1306
    /// # use time_macros::date;
1307
    /// assert!(date!(1970-01-01).with_hms_micro(0, 0, 0, 0).is_ok());
1308
    /// assert!(date!(1970-01-01).with_hms_micro(24, 0, 0, 0).is_err());
1309
    /// ```
1310
    #[inline]
1311
0
    pub const fn with_hms_micro(
1312
0
        self,
1313
0
        hour: u8,
1314
0
        minute: u8,
1315
0
        second: u8,
1316
0
        microsecond: u32,
1317
0
    ) -> Result<PrimitiveDateTime, error::ComponentRange> {
1318
0
        Ok(PrimitiveDateTime::new(
1319
0
            self,
1320
0
            const_try!(Time::from_hms_micro(hour, minute, second, microsecond)),
1321
        ))
1322
0
    }
1323
1324
    /// Attempt to create a [`PrimitiveDateTime`] using the existing date and the provided time.
1325
    ///
1326
    /// ```rust
1327
    /// # use time_macros::date;
1328
    /// assert!(date!(1970-01-01).with_hms_nano(0, 0, 0, 0).is_ok());
1329
    /// assert!(date!(1970-01-01).with_hms_nano(24, 0, 0, 0).is_err());
1330
    /// ```
1331
    #[inline]
1332
0
    pub const fn with_hms_nano(
1333
0
        self,
1334
0
        hour: u8,
1335
0
        minute: u8,
1336
0
        second: u8,
1337
0
        nanosecond: u32,
1338
0
    ) -> Result<PrimitiveDateTime, error::ComponentRange> {
1339
0
        Ok(PrimitiveDateTime::new(
1340
0
            self,
1341
0
            const_try!(Time::from_hms_nano(hour, minute, second, nanosecond)),
1342
        ))
1343
0
    }
1344
}
1345
1346
#[cfg(feature = "formatting")]
1347
impl Date {
1348
    /// Format the `Date` using the provided [format description](crate::format_description).
1349
    #[inline]
1350
    pub fn format_into(
1351
        self,
1352
        output: &mut (impl io::Write + ?Sized),
1353
        format: &(impl Formattable + ?Sized),
1354
    ) -> Result<usize, error::Format> {
1355
        format.format_into(output, Some(self), None, None)
1356
    }
1357
1358
    /// Format the `Date` using the provided [format description](crate::format_description).
1359
    ///
1360
    /// ```rust
1361
    /// # use time::{format_description};
1362
    /// # use time_macros::date;
1363
    /// let format = format_description::parse("[year]-[month]-[day]")?;
1364
    /// assert_eq!(date!(2020-01-02).format(&format)?, "2020-01-02");
1365
    /// # Ok::<_, time::Error>(())
1366
    /// ```
1367
    #[inline]
1368
    pub fn format(self, format: &(impl Formattable + ?Sized)) -> Result<String, error::Format> {
1369
        format.format(Some(self), None, None)
1370
    }
1371
}
1372
1373
#[cfg(feature = "parsing")]
1374
impl Date {
1375
    /// Parse a `Date` from the input using the provided [format
1376
    /// description](crate::format_description).
1377
    ///
1378
    /// ```rust
1379
    /// # use time::Date;
1380
    /// # use time_macros::{date, format_description};
1381
    /// let format = format_description!("[year]-[month]-[day]");
1382
    /// assert_eq!(Date::parse("2020-01-02", &format)?, date!(2020-01-02));
1383
    /// # Ok::<_, time::Error>(())
1384
    /// ```
1385
    #[inline]
1386
    pub fn parse(
1387
        input: &str,
1388
        description: &(impl Parsable + ?Sized),
1389
    ) -> Result<Self, error::Parse> {
1390
        description.parse_date(input.as_bytes())
1391
    }
1392
}
1393
1394
mod private {
1395
    #[non_exhaustive]
1396
    #[derive(Debug, Clone, Copy)]
1397
    pub struct DateMetadata {
1398
        /// The width of the year component, including the sign.
1399
        pub(super) year_width: u8,
1400
        /// Whether the sign should be displayed.
1401
        pub(super) display_sign: bool,
1402
        pub(super) year: i32,
1403
        pub(super) month: u8,
1404
        pub(super) day: u8,
1405
    }
1406
}
1407
use private::DateMetadata;
1408
1409
impl SmartDisplay for Date {
1410
    type Metadata = DateMetadata;
1411
1412
    #[inline]
1413
0
    fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Self> {
1414
0
        let (year, month, day) = self.to_calendar_date();
1415
1416
        // There is a minimum of four digits for any year.
1417
0
        let mut year_width = cmp::max(year.unsigned_abs().num_digits(), 4);
1418
0
        let display_sign = if !(0..10_000).contains(&year) {
1419
            // An extra character is required for the sign.
1420
0
            year_width += 1;
1421
0
            true
1422
        } else {
1423
0
            false
1424
        };
1425
1426
0
        let formatted_width = year_width.extend::<usize>()
1427
0
            + smart_display::padded_width_of!(
1428
0
                "-",
1429
0
                u8::from(month) => width(2),
1430
0
                "-",
1431
0
                day => width(2),
1432
0
            );
1433
1434
0
        Metadata::new(
1435
0
            formatted_width,
1436
0
            self,
1437
0
            DateMetadata {
1438
0
                year_width,
1439
0
                display_sign,
1440
0
                year,
1441
0
                month: u8::from(month),
1442
0
                day,
1443
0
            },
1444
        )
1445
0
    }
1446
1447
    #[inline]
1448
0
    fn fmt_with_metadata(
1449
0
        &self,
1450
0
        f: &mut fmt::Formatter<'_>,
1451
0
        metadata: Metadata<Self>,
1452
0
    ) -> fmt::Result {
1453
        let DateMetadata {
1454
0
            year_width,
1455
0
            display_sign,
1456
0
            year,
1457
0
            month,
1458
0
            day,
1459
0
        } = *metadata;
1460
0
        let year_width = year_width.extend();
1461
1462
0
        if display_sign {
1463
0
            f.pad_with_width(
1464
0
                metadata.unpadded_width(),
1465
0
                format_args!("{year:+0year_width$}-{month:02}-{day:02}"),
1466
            )
1467
        } else {
1468
0
            f.pad_with_width(
1469
0
                metadata.unpadded_width(),
1470
0
                format_args!("{year:0year_width$}-{month:02}-{day:02}"),
1471
            )
1472
        }
1473
0
    }
1474
}
1475
1476
impl fmt::Display for Date {
1477
    #[inline]
1478
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1479
0
        SmartDisplay::fmt(self, f)
1480
0
    }
1481
}
1482
1483
impl fmt::Debug for Date {
1484
    #[inline]
1485
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
1486
0
        fmt::Display::fmt(self, f)
1487
0
    }
1488
}
1489
1490
impl Add<Duration> for Date {
1491
    type Output = Self;
1492
1493
    /// # Panics
1494
    ///
1495
    /// This may panic if an overflow occurs.
1496
    #[inline]
1497
    #[track_caller]
1498
0
    fn add(self, duration: Duration) -> Self::Output {
1499
0
        self.checked_add(duration)
1500
0
            .expect("overflow adding duration to date")
1501
0
    }
1502
}
1503
1504
impl Add<StdDuration> for Date {
1505
    type Output = Self;
1506
1507
    /// # Panics
1508
    ///
1509
    /// This may panic if an overflow occurs.
1510
    #[inline]
1511
    #[track_caller]
1512
83.4k
    fn add(self, duration: StdDuration) -> Self::Output {
1513
83.4k
        self.checked_add_std(duration)
1514
83.4k
            .expect("overflow adding duration to date")
1515
83.4k
    }
<time::date::Date as core::ops::arith::Add<core::time::Duration>>::add
Line
Count
Source
1512
83.4k
    fn add(self, duration: StdDuration) -> Self::Output {
1513
83.4k
        self.checked_add_std(duration)
1514
83.4k
            .expect("overflow adding duration to date")
1515
83.4k
    }
Unexecuted instantiation: <time::date::Date as core::ops::arith::Add<core::time::Duration>>::add
1516
}
1517
1518
impl_add_assign!(Date: Duration, StdDuration);
1519
1520
impl Sub<Duration> for Date {
1521
    type Output = Self;
1522
1523
    /// # Panics
1524
    ///
1525
    /// This may panic if an overflow occurs.
1526
    #[inline]
1527
    #[track_caller]
1528
0
    fn sub(self, duration: Duration) -> Self::Output {
1529
0
        self.checked_sub(duration)
1530
0
            .expect("overflow subtracting duration from date")
1531
0
    }
1532
}
1533
1534
impl Sub<StdDuration> for Date {
1535
    type Output = Self;
1536
1537
    /// # Panics
1538
    ///
1539
    /// This may panic if an overflow occurs.
1540
    #[inline]
1541
    #[track_caller]
1542
0
    fn sub(self, duration: StdDuration) -> Self::Output {
1543
0
        self.checked_sub_std(duration)
1544
0
            .expect("overflow subtracting duration from date")
1545
0
    }
Unexecuted instantiation: <time::date::Date as core::ops::arith::Sub<core::time::Duration>>::sub
Unexecuted instantiation: <time::date::Date as core::ops::arith::Sub<core::time::Duration>>::sub
1546
}
1547
1548
impl_sub_assign!(Date: Duration, StdDuration);
1549
1550
impl Sub for Date {
1551
    type Output = Duration;
1552
1553
    #[inline]
1554
0
    fn sub(self, other: Self) -> Self::Output {
1555
0
        Duration::days((self.to_julian_day() - other.to_julian_day()).extend())
1556
0
    }
1557
}