Coverage Report

Created: 2026-09-04 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/chrono/src/naive/date/mod.rs
Line
Count
Source
1
// This is a part of Chrono.
2
// See README.md and LICENSE.txt for details.
3
4
//! ISO 8601 calendar date without timezone.
5
//!
6
//! The implementation is optimized for determining year, month, day and day of week.
7
//!
8
//! Format of `NaiveDate`:
9
//! `YYYY_YYYY_YYYY_YYYY_YYYO_OOOO_OOOO_LWWW`
10
//! `Y`: Year
11
//! `O`: Ordinal
12
//! `L`: leap year flag (1 = common year, 0 is leap year)
13
//! `W`: weekday before the first day of the year
14
//! `LWWW`: will also be referred to as the year flags (`F`)
15
16
#[cfg(feature = "alloc")]
17
use core::borrow::Borrow;
18
use core::iter::FusedIterator;
19
use core::num::NonZeroI32;
20
use core::ops::{Add, AddAssign, Sub, SubAssign};
21
use core::{fmt, str};
22
23
#[cfg(any(feature = "rkyv", feature = "rkyv-16", feature = "rkyv-32", feature = "rkyv-64"))]
24
use rkyv::{Archive, Deserialize, Serialize};
25
26
/// L10n locales.
27
#[cfg(all(feature = "unstable-locales", feature = "alloc"))]
28
use pure_rust_locales::Locale;
29
30
use super::internals::{Mdf, YearFlags};
31
use crate::datetime::UNIX_EPOCH_DAY;
32
#[cfg(feature = "alloc")]
33
use crate::format::DelayedFormat;
34
use crate::format::{
35
    Item, Numeric, Pad, ParseError, ParseResult, Parsed, StrftimeItems, parse, parse_and_remainder,
36
    write_hundreds,
37
};
38
use crate::month::Months;
39
use crate::naive::{Days, IsoWeek, NaiveDateTime, NaiveTime, NaiveWeek};
40
use crate::{Datelike, TimeDelta, Weekday};
41
use crate::{expect, try_opt};
42
43
#[cfg(test)]
44
mod tests;
45
46
/// ISO 8601 calendar date without timezone.
47
/// Allows for every [proleptic Gregorian date] from Jan 1, 262145 BCE to Dec 31, 262143 CE.
48
/// Also supports the conversion from ISO 8601 ordinal and week date.
49
///
50
/// # Calendar Date
51
///
52
/// The ISO 8601 **calendar date** follows the proleptic Gregorian calendar.
53
/// It is like a normal civil calendar but note some slight differences:
54
///
55
/// * Dates before the Gregorian calendar's inception in 1582 are defined via the extrapolation.
56
///   Be careful, as historical dates are often noted in the Julian calendar and others
57
///   and the transition to Gregorian may differ across countries (as late as early 20C).
58
///
59
///   (Some example: Both Shakespeare from Britain and Cervantes from Spain seemingly died
60
///   on the same calendar date---April 23, 1616---but in the different calendar.
61
///   Britain used the Julian calendar at that time, so Shakespeare's death is later.)
62
///
63
/// * ISO 8601 calendars have the year 0, which is 1 BCE (a year before 1 CE).
64
///   If you need a typical BCE/BC and CE/AD notation for year numbers,
65
///   use the [`Datelike::year_ce`] method.
66
///
67
/// # Week Date
68
///
69
/// The ISO 8601 **week date** is a triple of year number, week number
70
/// and [day of the week](Weekday) with the following rules:
71
///
72
/// * A week consists of Monday through Sunday, and is always numbered within some year.
73
///   The week number ranges from 1 to 52 or 53 depending on the year.
74
///
75
/// * The week 1 of given year is defined as the first week containing January 4 of that year,
76
///   or equivalently, the first week containing four or more days in that year.
77
///
78
/// * The year number in the week date may *not* correspond to the actual Gregorian year.
79
///   For example, January 3, 2016 (Sunday) was on the last (53rd) week of 2015.
80
///
81
/// Chrono's date types default to the ISO 8601 [calendar date](#calendar-date), but
82
/// [`Datelike::iso_week`] and [`Datelike::weekday`] methods can be used to get the corresponding
83
/// week date.
84
///
85
/// # Ordinal Date
86
///
87
/// The ISO 8601 **ordinal date** is a pair of year number and day of the year ("ordinal").
88
/// The ordinal number ranges from 1 to 365 or 366 depending on the year.
89
/// The year number is the same as that of the [calendar date](#calendar-date).
90
///
91
/// This is currently the internal format of Chrono's date types.
92
///
93
/// [proleptic Gregorian date]: crate::NaiveDate#calendar-date
94
#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Copy, Clone)]
95
#[cfg_attr(
96
    any(feature = "rkyv", feature = "rkyv-16", feature = "rkyv-32", feature = "rkyv-64"),
97
    derive(Archive, Deserialize, Serialize),
98
    archive(compare(PartialEq, PartialOrd)),
99
    archive_attr(derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash))
100
)]
101
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
102
pub struct NaiveDate {
103
    yof: NonZeroI32, // (year << 13) | of
104
}
105
106
/// The minimum possible `NaiveDate` (January 1, 262145 BCE).
107
#[deprecated(since = "0.4.20", note = "Use NaiveDate::MIN instead")]
108
pub const MIN_DATE: NaiveDate = NaiveDate::MIN;
109
/// The maximum possible `NaiveDate` (December 31, 262143 CE).
110
#[deprecated(since = "0.4.20", note = "Use NaiveDate::MAX instead")]
111
pub const MAX_DATE: NaiveDate = NaiveDate::MAX;
112
113
#[cfg(all(feature = "arbitrary", feature = "std"))]
114
impl arbitrary::Arbitrary<'_> for NaiveDate {
115
    fn arbitrary(u: &mut arbitrary::Unstructured) -> arbitrary::Result<NaiveDate> {
116
        let year = u.int_in_range(MIN_YEAR..=MAX_YEAR)?;
117
        let max_days = YearFlags::from_year(year).ndays();
118
        let ord = u.int_in_range(1..=max_days)?;
119
        NaiveDate::from_yo_opt(year, ord).ok_or(arbitrary::Error::IncorrectFormat)
120
    }
121
}
122
123
impl NaiveDate {
124
2.96k
    pub(crate) fn weeks_from(&self, day: Weekday) -> i32 {
125
2.96k
        (self.ordinal() as i32 - self.weekday().days_since(day) as i32 + 6) / 7
126
2.96k
    }
127
128
    /// Makes a new `NaiveDate` from year, ordinal and flags.
129
    /// Does not check whether the flags are correct for the provided year.
130
2.18k
    const fn from_ordinal_and_flags(
131
2.18k
        year: i32,
132
2.18k
        ordinal: u32,
133
2.18k
        flags: YearFlags,
134
2.18k
    ) -> Option<NaiveDate> {
135
2.18k
        if year < MIN_YEAR || year > MAX_YEAR {
136
115
            return None; // Out-of-range
137
2.06k
        }
138
2.06k
        if ordinal == 0 || ordinal > 366 {
139
0
            return None; // Invalid
140
2.06k
        }
141
2.06k
        debug_assert!(YearFlags::from_year(year).0 == flags.0);
142
2.06k
        let yof = (year << 13) | (ordinal << 4) as i32 | flags.0 as i32;
143
2.06k
        match yof & OL_MASK <= MAX_OL {
144
2.06k
            true => Some(NaiveDate::from_yof(yof)),
145
1
            false => None, // Does not exist: Ordinal 366 in a common year.
146
        }
147
2.18k
    }
148
149
    /// Makes a new `NaiveDate` from year and packed month-day-flags.
150
    /// Does not check whether the flags are correct for the provided year.
151
1.86k
    const fn from_mdf(year: i32, mdf: Mdf) -> Option<NaiveDate> {
152
1.86k
        if year < MIN_YEAR || year > MAX_YEAR {
153
43
            return None; // Out-of-range
154
1.82k
        }
155
1.82k
        Some(NaiveDate::from_yof((year << 13) | try_opt!(mdf.ordinal_and_flags())))
156
1.86k
    }
157
158
    /// Makes a new `NaiveDate` from the [calendar date](#calendar-date)
159
    /// (year, month and day).
160
    ///
161
    /// # Panics
162
    ///
163
    /// Panics if the specified calendar day does not exist, on invalid values for `month` or `day`,
164
    /// or if `year` is out of range for `NaiveDate`.
165
    #[deprecated(since = "0.4.23", note = "use `from_ymd_opt()` instead")]
166
    #[must_use]
167
0
    pub const fn from_ymd(year: i32, month: u32, day: u32) -> NaiveDate {
168
0
        expect(NaiveDate::from_ymd_opt(year, month, day), "invalid or out-of-range date")
169
0
    }
170
171
    /// Makes a new `NaiveDate` from the [calendar date](#calendar-date)
172
    /// (year, month and day).
173
    ///
174
    /// # Errors
175
    ///
176
    /// Returns `None` if:
177
    /// - The specified calendar day does not exist (for example 2023-04-31).
178
    /// - The value for `month` or `day` is invalid.
179
    /// - `year` is out of range for `NaiveDate`.
180
    ///
181
    /// # Example
182
    ///
183
    /// ```
184
    /// use chrono::NaiveDate;
185
    ///
186
    /// let from_ymd_opt = NaiveDate::from_ymd_opt;
187
    ///
188
    /// assert!(from_ymd_opt(2015, 3, 14).is_some());
189
    /// assert!(from_ymd_opt(2015, 0, 14).is_none());
190
    /// assert!(from_ymd_opt(2015, 2, 29).is_none());
191
    /// assert!(from_ymd_opt(-4, 2, 29).is_some()); // 5 BCE is a leap year
192
    /// assert!(from_ymd_opt(400000, 1, 1).is_none());
193
    /// assert!(from_ymd_opt(-400000, 1, 1).is_none());
194
    /// ```
195
    #[must_use]
196
1.87k
    pub const fn from_ymd_opt(year: i32, month: u32, day: u32) -> Option<NaiveDate> {
197
1.87k
        let flags = YearFlags::from_year(year);
198
199
1.87k
        if let Some(mdf) = Mdf::new(month, day, flags) {
200
1.86k
            NaiveDate::from_mdf(year, mdf)
201
        } else {
202
7
            None
203
        }
204
1.87k
    }
205
206
    /// Makes a new `NaiveDate` from the [ordinal date](#ordinal-date)
207
    /// (year and day of the year).
208
    ///
209
    /// # Panics
210
    ///
211
    /// Panics if the specified ordinal day does not exist, on invalid values for `ordinal`, or if
212
    /// `year` is out of range for `NaiveDate`.
213
    #[deprecated(since = "0.4.23", note = "use `from_yo_opt()` instead")]
214
    #[must_use]
215
0
    pub const fn from_yo(year: i32, ordinal: u32) -> NaiveDate {
216
0
        expect(NaiveDate::from_yo_opt(year, ordinal), "invalid or out-of-range date")
217
0
    }
218
219
    /// Makes a new `NaiveDate` from the [ordinal date](#ordinal-date)
220
    /// (year and day of the year).
221
    ///
222
    /// # Errors
223
    ///
224
    /// Returns `None` if:
225
    /// - The specified ordinal day does not exist (for example 2023-366).
226
    /// - The value for `ordinal` is invalid (for example: `0`, `400`).
227
    /// - `year` is out of range for `NaiveDate`.
228
    ///
229
    /// # Example
230
    ///
231
    /// ```
232
    /// use chrono::NaiveDate;
233
    ///
234
    /// let from_yo_opt = NaiveDate::from_yo_opt;
235
    ///
236
    /// assert!(from_yo_opt(2015, 100).is_some());
237
    /// assert!(from_yo_opt(2015, 0).is_none());
238
    /// assert!(from_yo_opt(2015, 365).is_some());
239
    /// assert!(from_yo_opt(2015, 366).is_none());
240
    /// assert!(from_yo_opt(-4, 366).is_some()); // 5 BCE is a leap year
241
    /// assert!(from_yo_opt(400000, 1).is_none());
242
    /// assert!(from_yo_opt(-400000, 1).is_none());
243
    /// ```
244
    #[must_use]
245
949
    pub const fn from_yo_opt(year: i32, ordinal: u32) -> Option<NaiveDate> {
246
949
        let flags = YearFlags::from_year(year);
247
949
        NaiveDate::from_ordinal_and_flags(year, ordinal, flags)
248
949
    }
249
250
    /// Makes a new `NaiveDate` from the [ISO week date](#week-date)
251
    /// (year, week number and day of the week).
252
    /// The resulting `NaiveDate` may have a different year from the input year.
253
    ///
254
    /// # Panics
255
    ///
256
    /// Panics if the specified week does not exist in that year, on invalid values for `week`, or
257
    /// if the resulting date is out of range for `NaiveDate`.
258
    #[deprecated(since = "0.4.23", note = "use `from_isoywd_opt()` instead")]
259
    #[must_use]
260
0
    pub const fn from_isoywd(year: i32, week: u32, weekday: Weekday) -> NaiveDate {
261
0
        expect(NaiveDate::from_isoywd_opt(year, week, weekday), "invalid or out-of-range date")
262
0
    }
263
264
    /// Makes a new `NaiveDate` from the [ISO week date](#week-date)
265
    /// (year, week number and day of the week).
266
    /// The resulting `NaiveDate` may have a different year from the input year.
267
    ///
268
    /// # Errors
269
    ///
270
    /// Returns `None` if:
271
    /// - The specified week does not exist in that year (for example 2023 week 53).
272
    /// - The value for `week` is invalid (for example: `0`, `60`).
273
    /// - If the resulting date is out of range for `NaiveDate`.
274
    ///
275
    /// # Example
276
    ///
277
    /// ```
278
    /// use chrono::{NaiveDate, Weekday};
279
    ///
280
    /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
281
    /// let from_isoywd_opt = NaiveDate::from_isoywd_opt;
282
    ///
283
    /// assert_eq!(from_isoywd_opt(2015, 0, Weekday::Sun), None);
284
    /// assert_eq!(from_isoywd_opt(2015, 10, Weekday::Sun), Some(from_ymd(2015, 3, 8)));
285
    /// assert_eq!(from_isoywd_opt(2015, 30, Weekday::Mon), Some(from_ymd(2015, 7, 20)));
286
    /// assert_eq!(from_isoywd_opt(2015, 60, Weekday::Mon), None);
287
    ///
288
    /// assert_eq!(from_isoywd_opt(400000, 10, Weekday::Fri), None);
289
    /// assert_eq!(from_isoywd_opt(-400000, 10, Weekday::Sat), None);
290
    /// ```
291
    ///
292
    /// The year number of ISO week date may differ from that of the calendar date.
293
    ///
294
    /// ```
295
    /// # use chrono::{NaiveDate, Weekday};
296
    /// # let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
297
    /// # let from_isoywd_opt = NaiveDate::from_isoywd_opt;
298
    /// //           Mo Tu We Th Fr Sa Su
299
    /// // 2014-W52  22 23 24 25 26 27 28    has 4+ days of new year,
300
    /// // 2015-W01  29 30 31  1  2  3  4 <- so this is the first week
301
    /// assert_eq!(from_isoywd_opt(2014, 52, Weekday::Sun), Some(from_ymd(2014, 12, 28)));
302
    /// assert_eq!(from_isoywd_opt(2014, 53, Weekday::Mon), None);
303
    /// assert_eq!(from_isoywd_opt(2015, 1, Weekday::Mon), Some(from_ymd(2014, 12, 29)));
304
    ///
305
    /// // 2015-W52  21 22 23 24 25 26 27    has 4+ days of old year,
306
    /// // 2015-W53  28 29 30 31  1  2  3 <- so this is the last week
307
    /// // 2016-W01   4  5  6  7  8  9 10
308
    /// assert_eq!(from_isoywd_opt(2015, 52, Weekday::Sun), Some(from_ymd(2015, 12, 27)));
309
    /// assert_eq!(from_isoywd_opt(2015, 53, Weekday::Sun), Some(from_ymd(2016, 1, 3)));
310
    /// assert_eq!(from_isoywd_opt(2015, 54, Weekday::Mon), None);
311
    /// assert_eq!(from_isoywd_opt(2016, 1, Weekday::Mon), Some(from_ymd(2016, 1, 4)));
312
    /// ```
313
    #[must_use]
314
178
    pub const fn from_isoywd_opt(year: i32, week: u32, weekday: Weekday) -> Option<NaiveDate> {
315
178
        let flags = YearFlags::from_year(year);
316
178
        let nweeks = flags.nisoweeks();
317
178
        if week == 0 || week > nweeks {
318
3
            return None;
319
175
        }
320
        // ordinal = week ordinal - delta
321
175
        let weekord = week * 7 + weekday as u32;
322
175
        let delta = flags.isoweek_delta();
323
175
        let (year, ordinal, flags) = if weekord <= delta {
324
            // ordinal < 1, previous year
325
            // `year - 1` would overflow for `year == i32::MIN`; such a year is
326
            // well out of range for `NaiveDate`, so return `None` as documented.
327
22
            let year = match year.checked_sub(1) {
328
22
                Some(year) => year,
329
0
                None => return None,
330
            };
331
22
            let prevflags = YearFlags::from_year(year);
332
22
            (year, weekord + prevflags.ndays() - delta, prevflags)
333
        } else {
334
153
            let ordinal = weekord - delta;
335
153
            let ndays = flags.ndays();
336
153
            if ordinal <= ndays {
337
                // this year
338
130
                (year, ordinal, flags)
339
            } else {
340
                // ordinal > ndays, next year
341
                // `year + 1` would overflow for `year == i32::MAX`; such a year is
342
                // well out of range for `NaiveDate`, so return `None` as documented.
343
23
                let year = match year.checked_add(1) {
344
23
                    Some(year) => year,
345
0
                    None => return None,
346
                };
347
23
                let nextflags = YearFlags::from_year(year);
348
23
                (year, ordinal - ndays, nextflags)
349
            }
350
        };
351
175
        NaiveDate::from_ordinal_and_flags(year, ordinal, flags)
352
178
    }
353
354
    /// Makes a new `NaiveDate` from a day's number in the proleptic Gregorian calendar, with
355
    /// January 1, 1 being day 1.
356
    ///
357
    /// # Panics
358
    ///
359
    /// Panics if the date is out of range.
360
    #[deprecated(since = "0.4.23", note = "use `from_num_days_from_ce_opt()` instead")]
361
    #[inline]
362
    #[must_use]
363
    pub const fn from_num_days_from_ce(days: i32) -> NaiveDate {
364
        expect(NaiveDate::from_num_days_from_ce_opt(days), "out-of-range date")
365
    }
366
367
    /// Makes a new `NaiveDate` from a day's number in the proleptic Gregorian calendar, with
368
    /// January 1, 1 being day 1.
369
    ///
370
    /// # Errors
371
    ///
372
    /// Returns `None` if the date is out of range.
373
    ///
374
    /// # Example
375
    ///
376
    /// ```
377
    /// use chrono::NaiveDate;
378
    ///
379
    /// let from_ndays_opt = NaiveDate::from_num_days_from_ce_opt;
380
    /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
381
    ///
382
    /// assert_eq!(from_ndays_opt(730_000), Some(from_ymd(1999, 9, 3)));
383
    /// assert_eq!(from_ndays_opt(1), Some(from_ymd(1, 1, 1)));
384
    /// assert_eq!(from_ndays_opt(0), Some(from_ymd(0, 12, 31)));
385
    /// assert_eq!(from_ndays_opt(-1), Some(from_ymd(0, 12, 30)));
386
    /// assert_eq!(from_ndays_opt(100_000_000), None);
387
    /// assert_eq!(from_ndays_opt(-100_000_000), None);
388
    /// ```
389
    #[must_use]
390
1.04k
    pub const fn from_num_days_from_ce_opt(days: i32) -> Option<NaiveDate> {
391
1.04k
        let days = try_opt!(days.checked_add(365)); // make December 31, 1 BCE equal to day 0
392
1.03k
        let year_div_400 = days.div_euclid(146_097);
393
1.03k
        let cycle = days.rem_euclid(146_097);
394
1.03k
        let (year_mod_400, ordinal) = cycle_to_yo(cycle as u32);
395
1.03k
        let flags = YearFlags::from_year_mod_400(year_mod_400 as i32);
396
1.03k
        NaiveDate::from_ordinal_and_flags(year_div_400 * 400 + year_mod_400 as i32, ordinal, flags)
397
1.04k
    }
398
399
    /// Makes a new `NaiveDate` from a day's number in the proleptic Gregorian calendar, with
400
    /// January 1, 1970 being day 0.
401
    ///
402
    /// # Errors
403
    ///
404
    /// Returns `None` if the date is out of range.
405
    ///
406
    /// # Example
407
    ///
408
    /// ```
409
    /// use chrono::NaiveDate;
410
    ///
411
    /// let from_ndays_opt = NaiveDate::from_epoch_days;
412
    /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
413
    ///
414
    /// assert_eq!(from_ndays_opt(-719_162), Some(from_ymd(1, 1, 1)));
415
    /// assert_eq!(from_ndays_opt(1), Some(from_ymd(1970, 1, 2)));
416
    /// assert_eq!(from_ndays_opt(0), Some(from_ymd(1970, 1, 1)));
417
    /// assert_eq!(from_ndays_opt(-1), Some(from_ymd(1969, 12, 31)));
418
    /// assert_eq!(from_ndays_opt(13036), Some(from_ymd(2005, 9, 10)));
419
    /// assert_eq!(from_ndays_opt(100_000_000), None);
420
    /// assert_eq!(from_ndays_opt(-100_000_000), None);
421
    /// ```
422
    #[must_use]
423
0
    pub const fn from_epoch_days(days: i32) -> Option<NaiveDate> {
424
0
        let ce_days = try_opt!(days.checked_add(UNIX_EPOCH_DAY as i32));
425
0
        NaiveDate::from_num_days_from_ce_opt(ce_days)
426
0
    }
427
428
    /// Makes a new `NaiveDate` by counting the number of occurrences of a particular day-of-week
429
    /// since the beginning of the given month. For instance, if you want the 2nd Friday of March
430
    /// 2017, you would use `NaiveDate::from_weekday_of_month(2017, 3, Weekday::Fri, 2)`.
431
    ///
432
    /// `n` is 1-indexed.
433
    ///
434
    /// # Panics
435
    ///
436
    /// Panics if the specified day does not exist in that month, on invalid values for `month` or
437
    /// `n`, or if `year` is out of range for `NaiveDate`.
438
    #[deprecated(since = "0.4.23", note = "use `from_weekday_of_month_opt()` instead")]
439
    #[must_use]
440
0
    pub const fn from_weekday_of_month(
441
0
        year: i32,
442
0
        month: u32,
443
0
        weekday: Weekday,
444
0
        n: u8,
445
0
    ) -> NaiveDate {
446
0
        expect(NaiveDate::from_weekday_of_month_opt(year, month, weekday, n), "out-of-range date")
447
0
    }
448
449
    /// Makes a new `NaiveDate` by counting the number of occurrences of a particular day-of-week
450
    /// since the beginning of the given month. For instance, if you want the 2nd Friday of March
451
    /// 2017, you would use `NaiveDate::from_weekday_of_month(2017, 3, Weekday::Fri, 2)`.
452
    ///
453
    /// `n` is 1-indexed.
454
    ///
455
    /// # Errors
456
    ///
457
    /// Returns `None` if:
458
    /// - The specified day does not exist in that month (for example the 5th Monday of Apr. 2023).
459
    /// - The value for `month` or `n` is invalid.
460
    /// - `year` is out of range for `NaiveDate`.
461
    ///
462
    /// # Example
463
    ///
464
    /// ```
465
    /// use chrono::{NaiveDate, Weekday};
466
    /// assert_eq!(
467
    ///     NaiveDate::from_weekday_of_month_opt(2017, 3, Weekday::Fri, 2),
468
    ///     NaiveDate::from_ymd_opt(2017, 3, 10)
469
    /// )
470
    /// ```
471
    #[must_use]
472
0
    pub const fn from_weekday_of_month_opt(
473
0
        year: i32,
474
0
        month: u32,
475
0
        weekday: Weekday,
476
0
        n: u8,
477
0
    ) -> Option<NaiveDate> {
478
0
        if n == 0 {
479
0
            return None;
480
0
        }
481
0
        let first = try_opt!(NaiveDate::from_ymd_opt(year, month, 1)).weekday();
482
0
        let first_to_dow = (7 + weekday.number_from_monday() - first.number_from_monday()) % 7;
483
0
        let day = (n - 1) as u32 * 7 + first_to_dow + 1;
484
0
        NaiveDate::from_ymd_opt(year, month, day)
485
0
    }
486
487
    /// Parses a string with the specified format string and returns a new `NaiveDate`.
488
    /// See the [`format::strftime` module](crate::format::strftime)
489
    /// on the supported escape sequences.
490
    ///
491
    /// # Example
492
    ///
493
    /// ```
494
    /// use chrono::NaiveDate;
495
    ///
496
    /// let parse_from_str = NaiveDate::parse_from_str;
497
    ///
498
    /// assert_eq!(
499
    ///     parse_from_str("2015-09-05", "%Y-%m-%d"),
500
    ///     Ok(NaiveDate::from_ymd_opt(2015, 9, 5).unwrap())
501
    /// );
502
    /// assert_eq!(
503
    ///     parse_from_str("5sep2015", "%d%b%Y"),
504
    ///     Ok(NaiveDate::from_ymd_opt(2015, 9, 5).unwrap())
505
    /// );
506
    /// ```
507
    ///
508
    /// Time and offset is ignored for the purpose of parsing.
509
    ///
510
    /// ```
511
    /// # use chrono::NaiveDate;
512
    /// # let parse_from_str = NaiveDate::parse_from_str;
513
    /// assert_eq!(
514
    ///     parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
515
    ///     Ok(NaiveDate::from_ymd_opt(2014, 5, 17).unwrap())
516
    /// );
517
    /// ```
518
    ///
519
    /// Out-of-bound dates or insufficient fields are errors.
520
    ///
521
    /// ```
522
    /// # use chrono::NaiveDate;
523
    /// # let parse_from_str = NaiveDate::parse_from_str;
524
    /// assert!(parse_from_str("2015/9", "%Y/%m").is_err());
525
    /// assert!(parse_from_str("2015/9/31", "%Y/%m/%d").is_err());
526
    /// ```
527
    ///
528
    /// All parsed fields should be consistent to each other, otherwise it's an error.
529
    ///
530
    /// ```
531
    /// # use chrono::NaiveDate;
532
    /// # let parse_from_str = NaiveDate::parse_from_str;
533
    /// assert!(parse_from_str("Sat, 09 Aug 2013", "%a, %d %b %Y").is_err());
534
    /// ```
535
0
    pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveDate> {
536
0
        let mut parsed = Parsed::new();
537
0
        parse(&mut parsed, s, StrftimeItems::new(fmt))?;
538
0
        parsed.to_naive_date()
539
0
    }
540
541
    /// Parses a string from a user-specified format into a new `NaiveDate` value, and a slice with
542
    /// the remaining portion of the string.
543
    /// See the [`format::strftime` module](crate::format::strftime)
544
    /// on the supported escape sequences.
545
    ///
546
    /// Similar to [`parse_from_str`](#method.parse_from_str).
547
    ///
548
    /// # Example
549
    ///
550
    /// ```rust
551
    /// # use chrono::{NaiveDate};
552
    /// let (date, remainder) =
553
    ///     NaiveDate::parse_and_remainder("2015-02-18 trailing text", "%Y-%m-%d").unwrap();
554
    /// assert_eq!(date, NaiveDate::from_ymd_opt(2015, 2, 18).unwrap());
555
    /// assert_eq!(remainder, " trailing text");
556
    /// ```
557
0
    pub fn parse_and_remainder<'a>(s: &'a str, fmt: &str) -> ParseResult<(NaiveDate, &'a str)> {
558
0
        let mut parsed = Parsed::new();
559
0
        let remainder = parse_and_remainder(&mut parsed, s, StrftimeItems::new(fmt))?;
560
0
        parsed.to_naive_date().map(|d| (d, remainder))
561
0
    }
562
563
    /// Add a duration in [`Months`] to the date
564
    ///
565
    /// Uses the last day of the month if the day does not exist in the resulting month.
566
    ///
567
    /// # Errors
568
    ///
569
    /// Returns `None` if the resulting date would be out of range.
570
    ///
571
    /// # Example
572
    ///
573
    /// ```
574
    /// # use chrono::{NaiveDate, Months};
575
    /// assert_eq!(
576
    ///     NaiveDate::from_ymd_opt(2022, 2, 20).unwrap().checked_add_months(Months::new(6)),
577
    ///     Some(NaiveDate::from_ymd_opt(2022, 8, 20).unwrap())
578
    /// );
579
    /// assert_eq!(
580
    ///     NaiveDate::from_ymd_opt(2022, 7, 31).unwrap().checked_add_months(Months::new(2)),
581
    ///     Some(NaiveDate::from_ymd_opt(2022, 9, 30).unwrap())
582
    /// );
583
    /// ```
584
    #[must_use]
585
0
    pub const fn checked_add_months(self, months: Months) -> Option<Self> {
586
0
        if months.0 == 0 {
587
0
            return Some(self);
588
0
        }
589
590
0
        match months.0 <= i32::MAX as u32 {
591
0
            true => self.diff_months(months.0 as i32),
592
0
            false => None,
593
        }
594
0
    }
595
596
    /// Subtract a duration in [`Months`] from the date
597
    ///
598
    /// Uses the last day of the month if the day does not exist in the resulting month.
599
    ///
600
    /// # Errors
601
    ///
602
    /// Returns `None` if the resulting date would be out of range.
603
    ///
604
    /// # Example
605
    ///
606
    /// ```
607
    /// # use chrono::{NaiveDate, Months};
608
    /// assert_eq!(
609
    ///     NaiveDate::from_ymd_opt(2022, 2, 20).unwrap().checked_sub_months(Months::new(6)),
610
    ///     Some(NaiveDate::from_ymd_opt(2021, 8, 20).unwrap())
611
    /// );
612
    ///
613
    /// assert_eq!(
614
    ///     NaiveDate::from_ymd_opt(2014, 1, 1)
615
    ///         .unwrap()
616
    ///         .checked_sub_months(Months::new(core::i32::MAX as u32 + 1)),
617
    ///     None
618
    /// );
619
    /// ```
620
    #[must_use]
621
0
    pub const fn checked_sub_months(self, months: Months) -> Option<Self> {
622
0
        if months.0 == 0 {
623
0
            return Some(self);
624
0
        }
625
626
0
        match months.0 <= i32::MAX as u32 {
627
0
            true => self.diff_months(-(months.0 as i32)),
628
0
            false => None,
629
        }
630
0
    }
631
632
0
    const fn diff_months(self, months: i32) -> Option<Self> {
633
0
        let months = try_opt!((self.year() * 12 + self.month() as i32 - 1).checked_add(months));
634
0
        let year = months.div_euclid(12);
635
0
        let month = months.rem_euclid(12) as u32 + 1;
636
637
        // Clamp original day in case new month is shorter
638
0
        let flags = YearFlags::from_year(year);
639
0
        let feb_days = if flags.ndays() == 366 { 29 } else { 28 };
640
0
        let days = [31, feb_days, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
641
0
        let day_max = days[(month - 1) as usize];
642
0
        let mut day = self.day();
643
0
        if day > day_max {
644
0
            day = day_max;
645
0
        };
646
647
0
        NaiveDate::from_ymd_opt(year, month, day)
648
0
    }
649
650
    /// Add a duration in [`Days`] to the date
651
    ///
652
    /// # Errors
653
    ///
654
    /// Returns `None` if the resulting date would be out of range.
655
    ///
656
    /// # Example
657
    ///
658
    /// ```
659
    /// # use chrono::{NaiveDate, Days};
660
    /// assert_eq!(
661
    ///     NaiveDate::from_ymd_opt(2022, 2, 20).unwrap().checked_add_days(Days::new(9)),
662
    ///     Some(NaiveDate::from_ymd_opt(2022, 3, 1).unwrap())
663
    /// );
664
    /// assert_eq!(
665
    ///     NaiveDate::from_ymd_opt(2022, 7, 31).unwrap().checked_add_days(Days::new(2)),
666
    ///     Some(NaiveDate::from_ymd_opt(2022, 8, 2).unwrap())
667
    /// );
668
    /// assert_eq!(
669
    ///     NaiveDate::from_ymd_opt(2022, 7, 31).unwrap().checked_add_days(Days::new(1000000000000)),
670
    ///     None
671
    /// );
672
    /// ```
673
    #[must_use]
674
0
    pub const fn checked_add_days(self, days: Days) -> Option<Self> {
675
0
        match days.0 <= i32::MAX as u64 {
676
0
            true => self.add_days(days.0 as i32),
677
0
            false => None,
678
        }
679
0
    }
680
681
    /// Subtract a duration in [`Days`] from the date
682
    ///
683
    /// # Errors
684
    ///
685
    /// Returns `None` if the resulting date would be out of range.
686
    ///
687
    /// # Example
688
    ///
689
    /// ```
690
    /// # use chrono::{NaiveDate, Days};
691
    /// assert_eq!(
692
    ///     NaiveDate::from_ymd_opt(2022, 2, 20).unwrap().checked_sub_days(Days::new(6)),
693
    ///     Some(NaiveDate::from_ymd_opt(2022, 2, 14).unwrap())
694
    /// );
695
    /// assert_eq!(
696
    ///     NaiveDate::from_ymd_opt(2022, 2, 20).unwrap().checked_sub_days(Days::new(1000000000000)),
697
    ///     None
698
    /// );
699
    /// ```
700
    #[must_use]
701
0
    pub const fn checked_sub_days(self, days: Days) -> Option<Self> {
702
0
        match days.0 <= i32::MAX as u64 {
703
0
            true => self.add_days(-(days.0 as i32)),
704
0
            false => None,
705
        }
706
0
    }
707
708
    /// Add a duration of `i32` days to the date.
709
53
    pub(crate) const fn add_days(self, days: i32) -> Option<Self> {
710
        // Fast path if the result is within the same year.
711
        // Also `DateTime::checked_(add|sub)_days` relies on this path, because if the value remains
712
        // within the year it doesn't do a check if the year is in range.
713
        // This way `DateTime:checked_(add|sub)_days(Days::new(0))` can be a no-op on dates were the
714
        // local datetime is beyond `NaiveDate::{MIN, MAX}.
715
        const ORDINAL_MASK: i32 = 0b1_1111_1111_0000;
716
53
        if let Some(ordinal) = ((self.yof() & ORDINAL_MASK) >> 4).checked_add(days) {
717
53
            if ordinal > 0 && ordinal <= (365 + self.leap_year() as i32) {
718
35
                let year_and_flags = self.yof() & !ORDINAL_MASK;
719
35
                return Some(NaiveDate::from_yof(year_and_flags | (ordinal << 4)));
720
18
            }
721
0
        }
722
        // do the full check
723
18
        let year = self.year();
724
18
        let (mut year_div_400, year_mod_400) = div_mod_floor(year, 400);
725
18
        let cycle = yo_to_cycle(year_mod_400 as u32, self.ordinal());
726
18
        let cycle = try_opt!((cycle as i32).checked_add(days));
727
18
        let (cycle_div_400y, cycle) = div_mod_floor(cycle, 146_097);
728
18
        year_div_400 += cycle_div_400y;
729
730
18
        let (year_mod_400, ordinal) = cycle_to_yo(cycle as u32);
731
18
        let flags = YearFlags::from_year_mod_400(year_mod_400 as i32);
732
18
        NaiveDate::from_ordinal_and_flags(year_div_400 * 400 + year_mod_400 as i32, ordinal, flags)
733
53
    }
734
735
    /// Makes a new `NaiveDateTime` from the current date and given `NaiveTime`.
736
    ///
737
    /// # Example
738
    ///
739
    /// ```
740
    /// use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
741
    ///
742
    /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
743
    /// let t = NaiveTime::from_hms_milli_opt(12, 34, 56, 789).unwrap();
744
    ///
745
    /// let dt: NaiveDateTime = d.and_time(t);
746
    /// assert_eq!(dt.date(), d);
747
    /// assert_eq!(dt.time(), t);
748
    /// ```
749
    #[inline]
750
    #[must_use]
751
2.13k
    pub const fn and_time(&self, time: NaiveTime) -> NaiveDateTime {
752
2.13k
        NaiveDateTime::new(*self, time)
753
2.13k
    }
754
755
    /// Makes a new `NaiveDateTime` from the current date, hour, minute and second.
756
    ///
757
    /// No [leap second](./struct.NaiveTime.html#leap-second-handling) is allowed here;
758
    /// use `NaiveDate::and_hms_*` methods with a subsecond parameter instead.
759
    ///
760
    /// # Panics
761
    ///
762
    /// Panics on invalid hour, minute and/or second.
763
    #[deprecated(since = "0.4.23", note = "use `and_hms_opt()` instead")]
764
    #[inline]
765
    #[must_use]
766
    pub const fn and_hms(&self, hour: u32, min: u32, sec: u32) -> NaiveDateTime {
767
        expect(self.and_hms_opt(hour, min, sec), "invalid time")
768
    }
769
770
    /// Makes a new `NaiveDateTime` from the current date, hour, minute and second.
771
    ///
772
    /// No [leap second](./struct.NaiveTime.html#leap-second-handling) is allowed here;
773
    /// use `NaiveDate::and_hms_*_opt` methods with a subsecond parameter instead.
774
    ///
775
    /// # Errors
776
    ///
777
    /// Returns `None` on invalid hour, minute and/or second.
778
    ///
779
    /// # Example
780
    ///
781
    /// ```
782
    /// use chrono::NaiveDate;
783
    ///
784
    /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
785
    /// assert!(d.and_hms_opt(12, 34, 56).is_some());
786
    /// assert!(d.and_hms_opt(12, 34, 60).is_none()); // use `and_hms_milli_opt` instead
787
    /// assert!(d.and_hms_opt(12, 60, 56).is_none());
788
    /// assert!(d.and_hms_opt(24, 34, 56).is_none());
789
    /// ```
790
    #[inline]
791
    #[must_use]
792
0
    pub const fn and_hms_opt(&self, hour: u32, min: u32, sec: u32) -> Option<NaiveDateTime> {
793
0
        let time = try_opt!(NaiveTime::from_hms_opt(hour, min, sec));
794
0
        Some(self.and_time(time))
795
0
    }
796
797
    /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and millisecond.
798
    ///
799
    /// The millisecond part is allowed to exceed 1,000 in order to represent a [leap second](
800
    /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`.
801
    ///
802
    /// # Panics
803
    ///
804
    /// Panics on invalid hour, minute, second and/or millisecond.
805
    #[deprecated(since = "0.4.23", note = "use `and_hms_milli_opt()` instead")]
806
    #[inline]
807
    #[must_use]
808
    pub const fn and_hms_milli(&self, hour: u32, min: u32, sec: u32, milli: u32) -> NaiveDateTime {
809
        expect(self.and_hms_milli_opt(hour, min, sec, milli), "invalid time")
810
    }
811
812
    /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and millisecond.
813
    ///
814
    /// The millisecond part is allowed to exceed 1,000 in order to represent a [leap second](
815
    /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`.
816
    ///
817
    /// # Errors
818
    ///
819
    /// Returns `None` on invalid hour, minute, second and/or millisecond.
820
    ///
821
    /// # Example
822
    ///
823
    /// ```
824
    /// use chrono::NaiveDate;
825
    ///
826
    /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
827
    /// assert!(d.and_hms_milli_opt(12, 34, 56, 789).is_some());
828
    /// assert!(d.and_hms_milli_opt(12, 34, 59, 1_789).is_some()); // leap second
829
    /// assert!(d.and_hms_milli_opt(12, 34, 59, 2_789).is_none());
830
    /// assert!(d.and_hms_milli_opt(12, 34, 60, 789).is_none());
831
    /// assert!(d.and_hms_milli_opt(12, 60, 56, 789).is_none());
832
    /// assert!(d.and_hms_milli_opt(24, 34, 56, 789).is_none());
833
    /// ```
834
    #[inline]
835
    #[must_use]
836
    pub const fn and_hms_milli_opt(
837
        &self,
838
        hour: u32,
839
        min: u32,
840
        sec: u32,
841
        milli: u32,
842
    ) -> Option<NaiveDateTime> {
843
        let time = try_opt!(NaiveTime::from_hms_milli_opt(hour, min, sec, milli));
844
        Some(self.and_time(time))
845
    }
846
847
    /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and microsecond.
848
    ///
849
    /// The microsecond part is allowed to exceed 1,000,000 in order to represent a [leap second](
850
    /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`.
851
    ///
852
    /// # Panics
853
    ///
854
    /// Panics on invalid hour, minute, second and/or microsecond.
855
    ///
856
    /// # Example
857
    ///
858
    /// ```
859
    /// use chrono::{Datelike, NaiveDate, NaiveDateTime, Timelike, Weekday};
860
    ///
861
    /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
862
    ///
863
    /// let dt: NaiveDateTime = d.and_hms_micro_opt(12, 34, 56, 789_012).unwrap();
864
    /// assert_eq!(dt.year(), 2015);
865
    /// assert_eq!(dt.weekday(), Weekday::Wed);
866
    /// assert_eq!(dt.second(), 56);
867
    /// assert_eq!(dt.nanosecond(), 789_012_000);
868
    /// ```
869
    #[deprecated(since = "0.4.23", note = "use `and_hms_micro_opt()` instead")]
870
    #[inline]
871
    #[must_use]
872
    pub const fn and_hms_micro(&self, hour: u32, min: u32, sec: u32, micro: u32) -> NaiveDateTime {
873
        expect(self.and_hms_micro_opt(hour, min, sec, micro), "invalid time")
874
    }
875
876
    /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and microsecond.
877
    ///
878
    /// The microsecond part is allowed to exceed 1,000,000 in order to represent a [leap second](
879
    /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`.
880
    ///
881
    /// # Errors
882
    ///
883
    /// Returns `None` on invalid hour, minute, second and/or microsecond.
884
    ///
885
    /// # Example
886
    ///
887
    /// ```
888
    /// use chrono::NaiveDate;
889
    ///
890
    /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
891
    /// assert!(d.and_hms_micro_opt(12, 34, 56, 789_012).is_some());
892
    /// assert!(d.and_hms_micro_opt(12, 34, 59, 1_789_012).is_some()); // leap second
893
    /// assert!(d.and_hms_micro_opt(12, 34, 59, 2_789_012).is_none());
894
    /// assert!(d.and_hms_micro_opt(12, 34, 60, 789_012).is_none());
895
    /// assert!(d.and_hms_micro_opt(12, 60, 56, 789_012).is_none());
896
    /// assert!(d.and_hms_micro_opt(24, 34, 56, 789_012).is_none());
897
    /// ```
898
    #[inline]
899
    #[must_use]
900
    pub const fn and_hms_micro_opt(
901
        &self,
902
        hour: u32,
903
        min: u32,
904
        sec: u32,
905
        micro: u32,
906
    ) -> Option<NaiveDateTime> {
907
        let time = try_opt!(NaiveTime::from_hms_micro_opt(hour, min, sec, micro));
908
        Some(self.and_time(time))
909
    }
910
911
    /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and nanosecond.
912
    ///
913
    /// The nanosecond part is allowed to exceed 1,000,000,000 in order to represent a [leap second](
914
    /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`.
915
    ///
916
    /// # Panics
917
    ///
918
    /// Panics on invalid hour, minute, second and/or nanosecond.
919
    #[deprecated(since = "0.4.23", note = "use `and_hms_nano_opt()` instead")]
920
    #[inline]
921
    #[must_use]
922
    pub const fn and_hms_nano(&self, hour: u32, min: u32, sec: u32, nano: u32) -> NaiveDateTime {
923
        expect(self.and_hms_nano_opt(hour, min, sec, nano), "invalid time")
924
    }
925
926
    /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and nanosecond.
927
    ///
928
    /// The nanosecond part is allowed to exceed 1,000,000,000 in order to represent a [leap second](
929
    /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`.
930
    ///
931
    /// # Errors
932
    ///
933
    /// Returns `None` on invalid hour, minute, second and/or nanosecond.
934
    ///
935
    /// # Example
936
    ///
937
    /// ```
938
    /// use chrono::NaiveDate;
939
    ///
940
    /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
941
    /// assert!(d.and_hms_nano_opt(12, 34, 56, 789_012_345).is_some());
942
    /// assert!(d.and_hms_nano_opt(12, 34, 59, 1_789_012_345).is_some()); // leap second
943
    /// assert!(d.and_hms_nano_opt(12, 34, 59, 2_789_012_345).is_none());
944
    /// assert!(d.and_hms_nano_opt(12, 34, 60, 789_012_345).is_none());
945
    /// assert!(d.and_hms_nano_opt(12, 60, 56, 789_012_345).is_none());
946
    /// assert!(d.and_hms_nano_opt(24, 34, 56, 789_012_345).is_none());
947
    /// ```
948
    #[inline]
949
    #[must_use]
950
    pub const fn and_hms_nano_opt(
951
        &self,
952
        hour: u32,
953
        min: u32,
954
        sec: u32,
955
        nano: u32,
956
    ) -> Option<NaiveDateTime> {
957
        let time = try_opt!(NaiveTime::from_hms_nano_opt(hour, min, sec, nano));
958
        Some(self.and_time(time))
959
    }
960
961
    /// Returns the packed month-day-flags.
962
    #[inline]
963
1.92k
    const fn mdf(&self) -> Mdf {
964
1.92k
        Mdf::from_ol((self.yof() & OL_MASK) >> 3, self.year_flags())
965
1.92k
    }
966
967
    /// Makes a new `NaiveDate` with the packed month-day-flags changed.
968
    ///
969
    /// Returns `None` when the resulting `NaiveDate` would be invalid.
970
    #[inline]
971
    const fn with_mdf(&self, mdf: Mdf) -> Option<NaiveDate> {
972
        debug_assert!(self.year_flags().0 == mdf.year_flags().0);
973
        match mdf.ordinal() {
974
            Some(ordinal) => {
975
                Some(NaiveDate::from_yof((self.yof() & !ORDINAL_MASK) | (ordinal << 4) as i32))
976
            }
977
            None => None, // Non-existing date
978
        }
979
    }
980
981
    /// Makes a new `NaiveDate` for the next calendar date.
982
    ///
983
    /// # Panics
984
    ///
985
    /// Panics when `self` is the last representable date.
986
    #[deprecated(since = "0.4.23", note = "use `succ_opt()` instead")]
987
    #[inline]
988
    #[must_use]
989
    pub const fn succ(&self) -> NaiveDate {
990
        expect(self.succ_opt(), "out of bound")
991
    }
992
993
    /// Makes a new `NaiveDate` for the next calendar date.
994
    ///
995
    /// # Errors
996
    ///
997
    /// Returns `None` when `self` is the last representable date.
998
    ///
999
    /// # Example
1000
    ///
1001
    /// ```
1002
    /// use chrono::NaiveDate;
1003
    ///
1004
    /// assert_eq!(
1005
    ///     NaiveDate::from_ymd_opt(2015, 6, 3).unwrap().succ_opt(),
1006
    ///     Some(NaiveDate::from_ymd_opt(2015, 6, 4).unwrap())
1007
    /// );
1008
    /// assert_eq!(NaiveDate::MAX.succ_opt(), None);
1009
    /// ```
1010
    #[inline]
1011
    #[must_use]
1012
126
    pub const fn succ_opt(&self) -> Option<NaiveDate> {
1013
126
        let new_ol = (self.yof() & OL_MASK) + (1 << 4);
1014
126
        match new_ol <= MAX_OL {
1015
42
            true => Some(NaiveDate::from_yof(self.yof() & !OL_MASK | new_ol)),
1016
84
            false => NaiveDate::from_yo_opt(self.year() + 1, 1),
1017
        }
1018
126
    }
1019
1020
    /// Makes a new `NaiveDate` for the previous calendar date.
1021
    ///
1022
    /// # Panics
1023
    ///
1024
    /// Panics when `self` is the first representable date.
1025
    #[deprecated(since = "0.4.23", note = "use `pred_opt()` instead")]
1026
    #[inline]
1027
    #[must_use]
1028
    pub const fn pred(&self) -> NaiveDate {
1029
        expect(self.pred_opt(), "out of bound")
1030
    }
1031
1032
    /// Makes a new `NaiveDate` for the previous calendar date.
1033
    ///
1034
    /// # Errors
1035
    ///
1036
    /// Returns `None` when `self` is the first representable date.
1037
    ///
1038
    /// # Example
1039
    ///
1040
    /// ```
1041
    /// use chrono::NaiveDate;
1042
    ///
1043
    /// assert_eq!(
1044
    ///     NaiveDate::from_ymd_opt(2015, 6, 3).unwrap().pred_opt(),
1045
    ///     Some(NaiveDate::from_ymd_opt(2015, 6, 2).unwrap())
1046
    /// );
1047
    /// assert_eq!(NaiveDate::MIN.pred_opt(), None);
1048
    /// ```
1049
    #[inline]
1050
    #[must_use]
1051
101
    pub const fn pred_opt(&self) -> Option<NaiveDate> {
1052
101
        let new_shifted_ordinal = (self.yof() & ORDINAL_MASK) - (1 << 4);
1053
101
        match new_shifted_ordinal > 0 {
1054
45
            true => Some(NaiveDate::from_yof(self.yof() & !ORDINAL_MASK | new_shifted_ordinal)),
1055
56
            false => NaiveDate::from_ymd_opt(self.year() - 1, 12, 31),
1056
        }
1057
101
    }
1058
1059
    /// Adds the number of whole days in the given `TimeDelta` to the current date.
1060
    ///
1061
    /// # Errors
1062
    ///
1063
    /// Returns `None` if the resulting date would be out of range.
1064
    ///
1065
    /// # Example
1066
    ///
1067
    /// ```
1068
    /// use chrono::{NaiveDate, TimeDelta};
1069
    ///
1070
    /// let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
1071
    /// assert_eq!(
1072
    ///     d.checked_add_signed(TimeDelta::try_days(40).unwrap()),
1073
    ///     Some(NaiveDate::from_ymd_opt(2015, 10, 15).unwrap())
1074
    /// );
1075
    /// assert_eq!(
1076
    ///     d.checked_add_signed(TimeDelta::try_days(-40).unwrap()),
1077
    ///     Some(NaiveDate::from_ymd_opt(2015, 7, 27).unwrap())
1078
    /// );
1079
    /// assert_eq!(d.checked_add_signed(TimeDelta::try_days(1_000_000_000).unwrap()), None);
1080
    /// assert_eq!(d.checked_add_signed(TimeDelta::try_days(-1_000_000_000).unwrap()), None);
1081
    /// assert_eq!(NaiveDate::MAX.checked_add_signed(TimeDelta::try_days(1).unwrap()), None);
1082
    /// ```
1083
    #[must_use]
1084
0
    pub const fn checked_add_signed(self, rhs: TimeDelta) -> Option<NaiveDate> {
1085
0
        let days = rhs.num_days();
1086
0
        if days < i32::MIN as i64 || days > i32::MAX as i64 {
1087
0
            return None;
1088
0
        }
1089
0
        self.add_days(days as i32)
1090
0
    }
1091
1092
    /// Subtracts the number of whole days in the given `TimeDelta` from the current date.
1093
    ///
1094
    /// # Errors
1095
    ///
1096
    /// Returns `None` if the resulting date would be out of range.
1097
    ///
1098
    /// # Example
1099
    ///
1100
    /// ```
1101
    /// use chrono::{NaiveDate, TimeDelta};
1102
    ///
1103
    /// let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
1104
    /// assert_eq!(
1105
    ///     d.checked_sub_signed(TimeDelta::try_days(40).unwrap()),
1106
    ///     Some(NaiveDate::from_ymd_opt(2015, 7, 27).unwrap())
1107
    /// );
1108
    /// assert_eq!(
1109
    ///     d.checked_sub_signed(TimeDelta::try_days(-40).unwrap()),
1110
    ///     Some(NaiveDate::from_ymd_opt(2015, 10, 15).unwrap())
1111
    /// );
1112
    /// assert_eq!(d.checked_sub_signed(TimeDelta::try_days(1_000_000_000).unwrap()), None);
1113
    /// assert_eq!(d.checked_sub_signed(TimeDelta::try_days(-1_000_000_000).unwrap()), None);
1114
    /// assert_eq!(NaiveDate::MIN.checked_sub_signed(TimeDelta::try_days(1).unwrap()), None);
1115
    /// ```
1116
    #[must_use]
1117
53
    pub const fn checked_sub_signed(self, rhs: TimeDelta) -> Option<NaiveDate> {
1118
53
        let days = -rhs.num_days();
1119
53
        if days < i32::MIN as i64 || days > i32::MAX as i64 {
1120
0
            return None;
1121
53
        }
1122
53
        self.add_days(days as i32)
1123
53
    }
1124
1125
    /// Subtracts another `NaiveDate` from the current date.
1126
    /// Returns a `TimeDelta` of integral numbers.
1127
    ///
1128
    /// This does not overflow or underflow at all,
1129
    /// as all possible output fits in the range of `TimeDelta`.
1130
    ///
1131
    /// # Example
1132
    ///
1133
    /// ```
1134
    /// use chrono::{NaiveDate, TimeDelta};
1135
    ///
1136
    /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
1137
    /// let since = NaiveDate::signed_duration_since;
1138
    ///
1139
    /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2014, 1, 1)), TimeDelta::zero());
1140
    /// assert_eq!(
1141
    ///     since(from_ymd(2014, 1, 1), from_ymd(2013, 12, 31)),
1142
    ///     TimeDelta::try_days(1).unwrap()
1143
    /// );
1144
    /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2014, 1, 2)), TimeDelta::try_days(-1).unwrap());
1145
    /// assert_eq!(
1146
    ///     since(from_ymd(2014, 1, 1), from_ymd(2013, 9, 23)),
1147
    ///     TimeDelta::try_days(100).unwrap()
1148
    /// );
1149
    /// assert_eq!(
1150
    ///     since(from_ymd(2014, 1, 1), from_ymd(2013, 1, 1)),
1151
    ///     TimeDelta::try_days(365).unwrap()
1152
    /// );
1153
    /// assert_eq!(
1154
    ///     since(from_ymd(2014, 1, 1), from_ymd(2010, 1, 1)),
1155
    ///     TimeDelta::try_days(365 * 4 + 1).unwrap()
1156
    /// );
1157
    /// assert_eq!(
1158
    ///     since(from_ymd(2014, 1, 1), from_ymd(1614, 1, 1)),
1159
    ///     TimeDelta::try_days(365 * 400 + 97).unwrap()
1160
    /// );
1161
    /// ```
1162
    #[must_use]
1163
0
    pub const fn signed_duration_since(self, rhs: Self) -> TimeDelta {
1164
0
        let year1 = self.year();
1165
0
        let year2 = rhs.year();
1166
0
        let (year1_div_400, year1_mod_400) = div_mod_floor(year1, 400);
1167
0
        let (year2_div_400, year2_mod_400) = div_mod_floor(year2, 400);
1168
0
        let cycle1 = yo_to_cycle(year1_mod_400 as u32, self.ordinal()) as i64;
1169
0
        let cycle2 = yo_to_cycle(year2_mod_400 as u32, rhs.ordinal()) as i64;
1170
0
        let days = (year1_div_400 as i64 - year2_div_400 as i64) * 146_097 + (cycle1 - cycle2);
1171
        // The range of `TimeDelta` is ca. 585 million years, the range of `NaiveDate` ca. 525.000
1172
        // years.
1173
0
        expect(TimeDelta::try_days(days), "always in range")
1174
0
    }
1175
1176
    /// Returns the absolute difference between two `NaiveDate`s measured as the number of days.
1177
    ///
1178
    /// This is always an integer, non-negative number, similar to `abs_diff` in `std`.
1179
    ///
1180
    /// # Example
1181
    ///
1182
    /// ```
1183
    /// # use chrono::{Days, NaiveDate};
1184
    /// #
1185
    /// let date1: NaiveDate = "2020-01-01".parse().unwrap();
1186
    /// let date2: NaiveDate = "2020-01-31".parse().unwrap();
1187
    /// assert_eq!(date2.abs_diff(date1), Days::new(30));
1188
    /// assert_eq!(date1.abs_diff(date2), Days::new(30));
1189
    /// ```
1190
0
    pub const fn abs_diff(self, rhs: Self) -> Days {
1191
0
        Days::new(i32::abs_diff(self.num_days_from_ce(), rhs.num_days_from_ce()) as u64)
1192
0
    }
1193
1194
    /// Returns the number of whole years from the given `base` until `self`.
1195
    ///
1196
    /// # Errors
1197
    ///
1198
    /// Returns `None` if `base > self`.
1199
    ///
1200
    /// # Example
1201
    ///
1202
    /// ```
1203
    /// # use chrono::{NaiveDate};
1204
    /// #
1205
    /// let base: NaiveDate = "2025-01-01".parse().unwrap();
1206
    /// let date: NaiveDate = "2030-01-01".parse().unwrap();
1207
    ///
1208
    /// assert_eq!(date.years_since(base), Some(5))
1209
    /// ```
1210
    #[must_use]
1211
0
    pub const fn years_since(&self, base: Self) -> Option<u32> {
1212
0
        let mut years = self.year() - base.year();
1213
        // Comparing tuples is not (yet) possible in const context. Instead we combine month and
1214
        // day into one `u32` for easy comparison.
1215
0
        if ((self.month() << 5) | self.day()) < ((base.month() << 5) | base.day()) {
1216
0
            years -= 1;
1217
0
        }
1218
1219
0
        match years >= 0 {
1220
0
            true => Some(years as u32),
1221
0
            false => None,
1222
        }
1223
0
    }
1224
1225
    /// Formats the date with the specified formatting items.
1226
    /// Otherwise it is the same as the ordinary `format` method.
1227
    ///
1228
    /// The `Iterator` of items should be `Clone`able,
1229
    /// since the resulting `DelayedFormat` value may be formatted multiple times.
1230
    ///
1231
    /// # Example
1232
    ///
1233
    /// ```
1234
    /// use chrono::format::strftime::StrftimeItems;
1235
    /// use chrono::NaiveDate;
1236
    ///
1237
    /// let fmt = StrftimeItems::new("%Y-%m-%d");
1238
    /// let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
1239
    /// assert_eq!(d.format_with_items(fmt.clone()).to_string(), "2015-09-05");
1240
    /// assert_eq!(d.format("%Y-%m-%d").to_string(), "2015-09-05");
1241
    /// ```
1242
    ///
1243
    /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
1244
    ///
1245
    /// ```
1246
    /// # use chrono::NaiveDate;
1247
    /// # use chrono::format::strftime::StrftimeItems;
1248
    /// # let fmt = StrftimeItems::new("%Y-%m-%d").clone();
1249
    /// # let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
1250
    /// assert_eq!(format!("{}", d.format_with_items(fmt)), "2015-09-05");
1251
    /// ```
1252
    #[cfg(feature = "alloc")]
1253
    #[inline]
1254
    #[must_use]
1255
    pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat<I>
1256
    where
1257
        I: Iterator<Item = B> + Clone,
1258
        B: Borrow<Item<'a>>,
1259
    {
1260
        DelayedFormat::new(Some(*self), None, items)
1261
    }
1262
1263
    /// Formats the date with the specified format string.
1264
    /// See the [`format::strftime` module](crate::format::strftime)
1265
    /// on the supported escape sequences.
1266
    ///
1267
    /// This returns a `DelayedFormat`,
1268
    /// which gets converted to a string only when actual formatting happens.
1269
    /// You may use the `to_string` method to get a `String`,
1270
    /// or just feed it into `print!` and other formatting macros.
1271
    /// (In this way it avoids the redundant memory allocation.)
1272
    ///
1273
    /// # Panics
1274
    ///
1275
    /// Converting or formatting the returned `DelayedFormat` panics if the format string is wrong.
1276
    /// Because of this delayed failure, you are recommended to immediately use the `DelayedFormat`
1277
    /// value.
1278
    ///
1279
    /// # Example
1280
    ///
1281
    /// ```
1282
    /// use chrono::NaiveDate;
1283
    ///
1284
    /// let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
1285
    /// assert_eq!(d.format("%Y-%m-%d").to_string(), "2015-09-05");
1286
    /// assert_eq!(d.format("%A, %-d %B, %C%y").to_string(), "Saturday, 5 September, 2015");
1287
    /// ```
1288
    ///
1289
    /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
1290
    ///
1291
    /// ```
1292
    /// # use chrono::NaiveDate;
1293
    /// # let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
1294
    /// assert_eq!(format!("{}", d.format("%Y-%m-%d")), "2015-09-05");
1295
    /// assert_eq!(format!("{}", d.format("%A, %-d %B, %C%y")), "Saturday, 5 September, 2015");
1296
    /// ```
1297
    #[cfg(feature = "alloc")]
1298
    #[inline]
1299
    #[must_use]
1300
    pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
1301
        self.format_with_items(StrftimeItems::new(fmt))
1302
    }
1303
1304
    /// Formats the date with the specified formatting items and locale.
1305
    #[cfg(all(feature = "unstable-locales", feature = "alloc"))]
1306
    #[inline]
1307
    #[must_use]
1308
    pub fn format_localized_with_items<'a, I, B>(
1309
        &self,
1310
        items: I,
1311
        locale: Locale,
1312
    ) -> DelayedFormat<I>
1313
    where
1314
        I: Iterator<Item = B> + Clone,
1315
        B: Borrow<Item<'a>>,
1316
    {
1317
        DelayedFormat::new_with_locale(Some(*self), None, items, locale)
1318
    }
1319
1320
    /// Formats the date with the specified format string and locale.
1321
    ///
1322
    /// See the [`crate::format::strftime`] module on the supported escape
1323
    /// sequences.
1324
    #[cfg(all(feature = "unstable-locales", feature = "alloc"))]
1325
    #[inline]
1326
    #[must_use]
1327
    pub fn format_localized<'a>(
1328
        &self,
1329
        fmt: &'a str,
1330
        locale: Locale,
1331
    ) -> DelayedFormat<StrftimeItems<'a>> {
1332
        self.format_localized_with_items(StrftimeItems::new_with_locale(fmt, locale), locale)
1333
    }
1334
1335
    /// Returns an iterator that steps by days across all representable dates.
1336
    ///
1337
    /// # Example
1338
    ///
1339
    /// ```
1340
    /// # use chrono::NaiveDate;
1341
    ///
1342
    /// let expected = [
1343
    ///     NaiveDate::from_ymd_opt(2016, 2, 27).unwrap(),
1344
    ///     NaiveDate::from_ymd_opt(2016, 2, 28).unwrap(),
1345
    ///     NaiveDate::from_ymd_opt(2016, 2, 29).unwrap(),
1346
    ///     NaiveDate::from_ymd_opt(2016, 3, 1).unwrap(),
1347
    /// ];
1348
    ///
1349
    /// let mut count = 0;
1350
    /// for (idx, d) in NaiveDate::from_ymd_opt(2016, 2, 27).unwrap().iter_days().take(4).enumerate() {
1351
    ///     assert_eq!(d, expected[idx]);
1352
    ///     count += 1;
1353
    /// }
1354
    /// assert_eq!(count, 4);
1355
    ///
1356
    /// // The iterator is double-ended: reversing a bounded range yields the same
1357
    /// // dates in reverse order.
1358
    /// for d in NaiveDate::from_ymd_opt(2016, 2, 27).unwrap().iter_days().take(4).rev() {
1359
    ///     count -= 1;
1360
    ///     assert_eq!(d, expected[count]);
1361
    /// }
1362
    /// ```
1363
    #[inline]
1364
    pub const fn iter_days(&self) -> NaiveDateDaysIterator {
1365
        NaiveDateDaysIterator { value: *self, end: NaiveDate::MAX }
1366
    }
1367
1368
    /// Returns an iterator that steps by weeks across all representable dates.
1369
    ///
1370
    /// # Example
1371
    ///
1372
    /// ```
1373
    /// # use chrono::NaiveDate;
1374
    ///
1375
    /// let expected = [
1376
    ///     NaiveDate::from_ymd_opt(2016, 2, 27).unwrap(),
1377
    ///     NaiveDate::from_ymd_opt(2016, 3, 5).unwrap(),
1378
    ///     NaiveDate::from_ymd_opt(2016, 3, 12).unwrap(),
1379
    ///     NaiveDate::from_ymd_opt(2016, 3, 19).unwrap(),
1380
    /// ];
1381
    ///
1382
    /// let mut count = 0;
1383
    /// for (idx, d) in NaiveDate::from_ymd_opt(2016, 2, 27).unwrap().iter_weeks().take(4).enumerate() {
1384
    ///     assert_eq!(d, expected[idx]);
1385
    ///     count += 1;
1386
    /// }
1387
    /// assert_eq!(count, 4);
1388
    ///
1389
    /// // The iterator is double-ended: reversing a bounded range yields the same
1390
    /// // dates in reverse order.
1391
    /// for d in NaiveDate::from_ymd_opt(2016, 2, 27).unwrap().iter_weeks().take(4).rev() {
1392
    ///     count -= 1;
1393
    ///     assert_eq!(d, expected[count]);
1394
    /// }
1395
    /// ```
1396
    #[inline]
1397
    pub const fn iter_weeks(&self) -> NaiveDateWeeksIterator {
1398
        // Align the exclusive upper bound to the weekly grid starting at `*self`, so
1399
        // that `next_back` yields the same weeks as `next`, only in reverse order.
1400
        let weeks = NaiveDate::MAX.signed_duration_since(*self).num_weeks();
1401
        // `weeks * 7` days is at most `NaiveDate::MAX - *self`, so this never overflows.
1402
        let end = match self.checked_add_days(Days::new((weeks * 7) as u64)) {
1403
            Some(end) => end,
1404
            None => *self,
1405
        };
1406
        NaiveDateWeeksIterator { value: *self, end }
1407
    }
1408
1409
    /// Returns the [`NaiveWeek`] that the date belongs to, starting with the [`Weekday`]
1410
    /// specified.
1411
    #[inline]
1412
    pub const fn week(&self, start: Weekday) -> NaiveWeek {
1413
        NaiveWeek::new(*self, start)
1414
    }
1415
1416
    /// Returns `true` if this is a leap year.
1417
    ///
1418
    /// ```
1419
    /// # use chrono::NaiveDate;
1420
    /// assert_eq!(NaiveDate::from_ymd_opt(2000, 1, 1).unwrap().leap_year(), true);
1421
    /// assert_eq!(NaiveDate::from_ymd_opt(2001, 1, 1).unwrap().leap_year(), false);
1422
    /// assert_eq!(NaiveDate::from_ymd_opt(2002, 1, 1).unwrap().leap_year(), false);
1423
    /// assert_eq!(NaiveDate::from_ymd_opt(2003, 1, 1).unwrap().leap_year(), false);
1424
    /// assert_eq!(NaiveDate::from_ymd_opt(2004, 1, 1).unwrap().leap_year(), true);
1425
    /// assert_eq!(NaiveDate::from_ymd_opt(2100, 1, 1).unwrap().leap_year(), false);
1426
    /// ```
1427
35
    pub const fn leap_year(&self) -> bool {
1428
35
        self.yof() & (0b1000) == 0
1429
35
    }
1430
1431
    // This duplicates `Datelike::year()`, because trait methods can't be const yet.
1432
    #[inline]
1433
4.28k
    const fn year(&self) -> i32 {
1434
4.28k
        self.yof() >> 13
1435
4.28k
    }
1436
1437
    /// Returns the day of year starting from 1.
1438
    // This duplicates `Datelike::ordinal()`, because trait methods can't be const yet.
1439
    #[inline]
1440
5.16k
    const fn ordinal(&self) -> u32 {
1441
5.16k
        ((self.yof() & ORDINAL_MASK) >> 4) as u32
1442
5.16k
    }
1443
1444
    // This duplicates `Datelike::month()`, because trait methods can't be const yet.
1445
    #[inline]
1446
986
    const fn month(&self) -> u32 {
1447
986
        self.mdf().month()
1448
986
    }
1449
1450
    // This duplicates `Datelike::day()`, because trait methods can't be const yet.
1451
    #[inline]
1452
943
    const fn day(&self) -> u32 {
1453
943
        self.mdf().day()
1454
943
    }
1455
1456
    /// Returns the day of week.
1457
    // This duplicates `Datelike::weekday()`, because trait methods can't be const yet.
1458
    #[inline]
1459
4.59k
    pub(super) const fn weekday(&self) -> Weekday {
1460
4.59k
        match (((self.yof() & ORDINAL_MASK) >> 4) + (self.yof() & WEEKDAY_FLAGS_MASK)) % 7 {
1461
504
            0 => Weekday::Mon,
1462
555
            1 => Weekday::Tue,
1463
555
            2 => Weekday::Wed,
1464
1.29k
            3 => Weekday::Thu,
1465
547
            4 => Weekday::Fri,
1466
528
            5 => Weekday::Sat,
1467
607
            _ => Weekday::Sun,
1468
        }
1469
4.59k
    }
1470
1471
    #[inline]
1472
3.47k
    const fn year_flags(&self) -> YearFlags {
1473
3.47k
        YearFlags((self.yof() & YEAR_FLAGS_MASK) as u8)
1474
3.47k
    }
1475
1476
    /// Counts the days in the proleptic Gregorian calendar, with January 1, Year 1 (CE) as day 1.
1477
    // This duplicates `Datelike::num_days_from_ce()`, because trait methods can't be const yet.
1478
635
    pub(crate) const fn num_days_from_ce(&self) -> i32 {
1479
        // we know this wouldn't overflow since year is limited to 1/2^13 of i32's full range.
1480
635
        let mut year = self.year() - 1;
1481
635
        let mut ndays = 0;
1482
635
        if year < 0 {
1483
115
            let excess = 1 + (-year) / 400;
1484
115
            year += excess * 400;
1485
115
            ndays -= excess * 146_097;
1486
520
        }
1487
635
        let div_100 = year / 100;
1488
635
        ndays += ((year * 1461) >> 2) - div_100 + (div_100 >> 2);
1489
635
        ndays + self.ordinal() as i32
1490
635
    }
1491
1492
    /// Counts the days in the proleptic Gregorian calendar, with January 1, Year 1970 as day 0.
1493
    ///
1494
    /// # Example
1495
    ///
1496
    /// ```
1497
    /// use chrono::NaiveDate;
1498
    ///
1499
    /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
1500
    ///
1501
    /// assert_eq!(from_ymd(1, 1, 1).to_epoch_days(), -719162);
1502
    /// assert_eq!(from_ymd(1970, 1, 1).to_epoch_days(), 0);
1503
    /// assert_eq!(from_ymd(2005, 9, 10).to_epoch_days(), 13036);
1504
    /// ```
1505
0
    pub const fn to_epoch_days(&self) -> i32 {
1506
0
        self.num_days_from_ce() - UNIX_EPOCH_DAY as i32
1507
0
    }
1508
1509
    /// Create a new `NaiveDate` from a raw year-ordinal-flags `i32`.
1510
    ///
1511
    /// In a valid value an ordinal is never `0`, and neither are the year flags. This method
1512
    /// doesn't do any validation in release builds.
1513
    #[inline]
1514
4.07k
    const fn from_yof(yof: i32) -> NaiveDate {
1515
        // The following are the invariants our ordinal and flags should uphold for a valid
1516
        // `NaiveDate`.
1517
4.07k
        debug_assert!(((yof & OL_MASK) >> 3) > 1);
1518
4.07k
        debug_assert!(((yof & OL_MASK) >> 3) <= MAX_OL);
1519
4.07k
        debug_assert!((yof & 0b111) != 000);
1520
4.07k
        NaiveDate { yof: unsafe { NonZeroI32::new_unchecked(yof) } }
1521
4.07k
    }
1522
1523
    /// Get the raw year-ordinal-flags `i32`.
1524
    #[inline]
1525
26.8k
    const fn yof(&self) -> i32 {
1526
26.8k
        self.yof.get()
1527
26.8k
    }
1528
1529
    /// The minimum possible `NaiveDate` (January 1, 262144 BCE).
1530
    pub const MIN: NaiveDate = NaiveDate::from_yof((MIN_YEAR << 13) | (1 << 4) | 0o12 /* D */);
1531
    /// The maximum possible `NaiveDate` (December 31, 262142 CE).
1532
    pub const MAX: NaiveDate =
1533
        NaiveDate::from_yof((MAX_YEAR << 13) | (365 << 4) | 0o16 /* G */);
1534
1535
    /// One day before the minimum possible `NaiveDate` (December 31, 262145 BCE).
1536
    pub(crate) const BEFORE_MIN: NaiveDate =
1537
        NaiveDate::from_yof(((MIN_YEAR - 1) << 13) | (366 << 4) | 0o07 /* FE */);
1538
    /// One day after the maximum possible `NaiveDate` (January 1, 262143 CE).
1539
    pub(crate) const AFTER_MAX: NaiveDate =
1540
        NaiveDate::from_yof(((MAX_YEAR + 1) << 13) | (1 << 4) | 0o17 /* F */);
1541
}
1542
1543
impl Datelike for NaiveDate {
1544
    /// Returns the year number in the [calendar date](#calendar-date).
1545
    ///
1546
    /// # Example
1547
    ///
1548
    /// ```
1549
    /// use chrono::{Datelike, NaiveDate};
1550
    ///
1551
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().year(), 2015);
1552
    /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().year(), -308); // 309 BCE
1553
    /// ```
1554
    #[inline]
1555
1.94k
    fn year(&self) -> i32 {
1556
1.94k
        self.year()
1557
1.94k
    }
1558
1559
    /// Returns the month number starting from 1.
1560
    ///
1561
    /// The return value ranges from 1 to 12.
1562
    ///
1563
    /// # Example
1564
    ///
1565
    /// ```
1566
    /// use chrono::{Datelike, NaiveDate};
1567
    ///
1568
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().month(), 9);
1569
    /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().month(), 3);
1570
    /// ```
1571
    #[inline]
1572
986
    fn month(&self) -> u32 {
1573
986
        self.month()
1574
986
    }
1575
1576
    /// Returns the month number starting from 0.
1577
    ///
1578
    /// The return value ranges from 0 to 11.
1579
    ///
1580
    /// # Example
1581
    ///
1582
    /// ```
1583
    /// use chrono::{Datelike, NaiveDate};
1584
    ///
1585
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().month0(), 8);
1586
    /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().month0(), 2);
1587
    /// ```
1588
    #[inline]
1589
0
    fn month0(&self) -> u32 {
1590
0
        self.month() - 1
1591
0
    }
1592
1593
    /// Returns the day of month starting from 1.
1594
    ///
1595
    /// The return value ranges from 1 to 31. (The last day of month differs by months.)
1596
    ///
1597
    /// # Example
1598
    ///
1599
    /// ```
1600
    /// use chrono::{Datelike, NaiveDate};
1601
    ///
1602
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().day(), 8);
1603
    /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().day(), 14);
1604
    /// ```
1605
    ///
1606
    /// Combined with [`NaiveDate::pred_opt`](#method.pred_opt),
1607
    /// one can determine the number of days in a particular month.
1608
    /// (Note that this panics when `year` is out of range.)
1609
    ///
1610
    /// ```
1611
    /// use chrono::{Datelike, NaiveDate};
1612
    ///
1613
    /// fn ndays_in_month(year: i32, month: u32) -> u32 {
1614
    ///     // the first day of the next month...
1615
    ///     let (y, m) = if month == 12 { (year + 1, 1) } else { (year, month + 1) };
1616
    ///     let d = NaiveDate::from_ymd_opt(y, m, 1).unwrap();
1617
    ///
1618
    ///     // ...is preceded by the last day of the original month
1619
    ///     d.pred_opt().unwrap().day()
1620
    /// }
1621
    ///
1622
    /// assert_eq!(ndays_in_month(2015, 8), 31);
1623
    /// assert_eq!(ndays_in_month(2015, 9), 30);
1624
    /// assert_eq!(ndays_in_month(2015, 12), 31);
1625
    /// assert_eq!(ndays_in_month(2016, 2), 29);
1626
    /// assert_eq!(ndays_in_month(2017, 2), 28);
1627
    /// ```
1628
    #[inline]
1629
943
    fn day(&self) -> u32 {
1630
943
        self.day()
1631
943
    }
1632
1633
    /// Returns the day of month starting from 0.
1634
    ///
1635
    /// The return value ranges from 0 to 30. (The last day of month differs by months.)
1636
    ///
1637
    /// # Example
1638
    ///
1639
    /// ```
1640
    /// use chrono::{Datelike, NaiveDate};
1641
    ///
1642
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().day0(), 7);
1643
    /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().day0(), 13);
1644
    /// ```
1645
    #[inline]
1646
    fn day0(&self) -> u32 {
1647
        self.mdf().day() - 1
1648
    }
1649
1650
    /// Returns the day of year starting from 1.
1651
    ///
1652
    /// The return value ranges from 1 to 366. (The last day of year differs by years.)
1653
    ///
1654
    /// # Example
1655
    ///
1656
    /// ```
1657
    /// use chrono::{Datelike, NaiveDate};
1658
    ///
1659
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().ordinal(), 251);
1660
    /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().ordinal(), 74);
1661
    /// ```
1662
    ///
1663
    /// Combined with [`NaiveDate::pred_opt`](#method.pred_opt),
1664
    /// one can determine the number of days in a particular year.
1665
    /// (Note that this panics when `year` is out of range.)
1666
    ///
1667
    /// ```
1668
    /// use chrono::{Datelike, NaiveDate};
1669
    ///
1670
    /// fn ndays_in_year(year: i32) -> u32 {
1671
    ///     // the first day of the next year...
1672
    ///     let d = NaiveDate::from_ymd_opt(year + 1, 1, 1).unwrap();
1673
    ///
1674
    ///     // ...is preceded by the last day of the original year
1675
    ///     d.pred_opt().unwrap().ordinal()
1676
    /// }
1677
    ///
1678
    /// assert_eq!(ndays_in_year(2015), 365);
1679
    /// assert_eq!(ndays_in_year(2016), 366);
1680
    /// assert_eq!(ndays_in_year(2017), 365);
1681
    /// assert_eq!(ndays_in_year(2000), 366);
1682
    /// assert_eq!(ndays_in_year(2100), 365);
1683
    /// ```
1684
    #[inline]
1685
2.26k
    fn ordinal(&self) -> u32 {
1686
2.26k
        ((self.yof() & ORDINAL_MASK) >> 4) as u32
1687
2.26k
    }
1688
1689
    /// Returns the day of year starting from 0.
1690
    ///
1691
    /// The return value ranges from 0 to 365. (The last day of year differs by years.)
1692
    ///
1693
    /// # Example
1694
    ///
1695
    /// ```
1696
    /// use chrono::{Datelike, NaiveDate};
1697
    ///
1698
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().ordinal0(), 250);
1699
    /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().ordinal0(), 73);
1700
    /// ```
1701
    #[inline]
1702
    fn ordinal0(&self) -> u32 {
1703
        self.ordinal() - 1
1704
    }
1705
1706
    /// Returns the day of week.
1707
    ///
1708
    /// # Example
1709
    ///
1710
    /// ```
1711
    /// use chrono::{Datelike, NaiveDate, Weekday};
1712
    ///
1713
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().weekday(), Weekday::Tue);
1714
    /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().weekday(), Weekday::Fri);
1715
    /// ```
1716
    #[inline]
1717
1.62k
    fn weekday(&self) -> Weekday {
1718
1.62k
        self.weekday()
1719
1.62k
    }
1720
1721
    #[inline]
1722
1.54k
    fn iso_week(&self) -> IsoWeek {
1723
1.54k
        IsoWeek::from_yof(self.year(), self.ordinal(), self.year_flags())
1724
1.54k
    }
1725
1726
    /// Makes a new `NaiveDate` with the year number changed, while keeping the same month and day.
1727
    ///
1728
    /// This method assumes you want to work on the date as a year-month-day value. Don't use it if
1729
    /// you want the ordinal to stay the same after changing the year, of if you want the week and
1730
    /// weekday values to stay the same.
1731
    ///
1732
    /// # Errors
1733
    ///
1734
    /// Returns `None` if:
1735
    /// - The resulting date does not exist (February 29 in a non-leap year).
1736
    /// - The year is out of range for a `NaiveDate`.
1737
    ///
1738
    /// # Examples
1739
    ///
1740
    /// ```
1741
    /// use chrono::{Datelike, NaiveDate};
1742
    ///
1743
    /// assert_eq!(
1744
    ///     NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_year(2016),
1745
    ///     Some(NaiveDate::from_ymd_opt(2016, 9, 8).unwrap())
1746
    /// );
1747
    /// assert_eq!(
1748
    ///     NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_year(-308),
1749
    ///     Some(NaiveDate::from_ymd_opt(-308, 9, 8).unwrap())
1750
    /// );
1751
    /// ```
1752
    ///
1753
    /// A leap day (February 29) is a case where this method can return `None`.
1754
    ///
1755
    /// ```
1756
    /// # use chrono::{NaiveDate, Datelike};
1757
    /// assert!(NaiveDate::from_ymd_opt(2016, 2, 29).unwrap().with_year(2015).is_none());
1758
    /// assert!(NaiveDate::from_ymd_opt(2016, 2, 29).unwrap().with_year(2020).is_some());
1759
    /// ```
1760
    ///
1761
    /// Don't use `with_year` if you want the ordinal date to stay the same:
1762
    ///
1763
    /// ```
1764
    /// # use chrono::{Datelike, NaiveDate};
1765
    /// assert_ne!(
1766
    ///     NaiveDate::from_yo_opt(2020, 100).unwrap().with_year(2023).unwrap(),
1767
    ///     NaiveDate::from_yo_opt(2023, 100).unwrap() // result is 2023-101
1768
    /// );
1769
    /// ```
1770
    #[inline]
1771
    fn with_year(&self, year: i32) -> Option<NaiveDate> {
1772
        // we need to operate with `mdf` since we should keep the month and day number as is
1773
        let mdf = self.mdf();
1774
1775
        // adjust the flags as needed
1776
        let flags = YearFlags::from_year(year);
1777
        let mdf = mdf.with_flags(flags);
1778
1779
        NaiveDate::from_mdf(year, mdf)
1780
    }
1781
1782
    /// Makes a new `NaiveDate` with the month number (starting from 1) changed.
1783
    ///
1784
    /// # Errors
1785
    ///
1786
    /// Returns `None` if:
1787
    /// - The resulting date does not exist (for example `month(4)` when day of the month is 31).
1788
    /// - The value for `month` is invalid.
1789
    ///
1790
    /// # Examples
1791
    ///
1792
    /// ```
1793
    /// use chrono::{Datelike, NaiveDate};
1794
    ///
1795
    /// assert_eq!(
1796
    ///     NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_month(10),
1797
    ///     Some(NaiveDate::from_ymd_opt(2015, 10, 8).unwrap())
1798
    /// );
1799
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_month(13), None); // No month 13
1800
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 30).unwrap().with_month(2), None); // No Feb 30
1801
    /// ```
1802
    ///
1803
    /// Don't combine multiple `Datelike::with_*` methods. The intermediate value may not exist.
1804
    ///
1805
    /// ```
1806
    /// use chrono::{Datelike, NaiveDate};
1807
    ///
1808
    /// fn with_year_month(date: NaiveDate, year: i32, month: u32) -> Option<NaiveDate> {
1809
    ///     date.with_year(year)?.with_month(month)
1810
    /// }
1811
    /// let d = NaiveDate::from_ymd_opt(2020, 2, 29).unwrap();
1812
    /// assert!(with_year_month(d, 2019, 1).is_none()); // fails because of invalid intermediate value
1813
    ///
1814
    /// // Correct version:
1815
    /// fn with_year_month_fixed(date: NaiveDate, year: i32, month: u32) -> Option<NaiveDate> {
1816
    ///     NaiveDate::from_ymd_opt(year, month, date.day())
1817
    /// }
1818
    /// let d = NaiveDate::from_ymd_opt(2020, 2, 29).unwrap();
1819
    /// assert_eq!(with_year_month_fixed(d, 2019, 1), NaiveDate::from_ymd_opt(2019, 1, 29));
1820
    /// ```
1821
    #[inline]
1822
    fn with_month(&self, month: u32) -> Option<NaiveDate> {
1823
        self.with_mdf(self.mdf().with_month(month)?)
1824
    }
1825
1826
    /// Makes a new `NaiveDate` with the month number (starting from 0) changed.
1827
    ///
1828
    /// # Errors
1829
    ///
1830
    /// Returns `None` if:
1831
    /// - The resulting date does not exist (for example `month0(3)` when day of the month is 31).
1832
    /// - The value for `month0` is invalid.
1833
    ///
1834
    /// # Example
1835
    ///
1836
    /// ```
1837
    /// use chrono::{Datelike, NaiveDate};
1838
    ///
1839
    /// assert_eq!(
1840
    ///     NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_month0(9),
1841
    ///     Some(NaiveDate::from_ymd_opt(2015, 10, 8).unwrap())
1842
    /// );
1843
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_month0(12), None); // No month 12
1844
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 30).unwrap().with_month0(1), None); // No Feb 30
1845
    /// ```
1846
    #[inline]
1847
    fn with_month0(&self, month0: u32) -> Option<NaiveDate> {
1848
        let month = month0.checked_add(1)?;
1849
        self.with_mdf(self.mdf().with_month(month)?)
1850
    }
1851
1852
    /// Makes a new `NaiveDate` with the day of month (starting from 1) changed.
1853
    ///
1854
    /// # Errors
1855
    ///
1856
    /// Returns `None` if:
1857
    /// - The resulting date does not exist (for example `day(31)` in April).
1858
    /// - The value for `day` is invalid.
1859
    ///
1860
    /// # Example
1861
    ///
1862
    /// ```
1863
    /// use chrono::{Datelike, NaiveDate};
1864
    ///
1865
    /// assert_eq!(
1866
    ///     NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_day(30),
1867
    ///     Some(NaiveDate::from_ymd_opt(2015, 9, 30).unwrap())
1868
    /// );
1869
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_day(31), None);
1870
    /// // no September 31
1871
    /// ```
1872
    #[inline]
1873
    fn with_day(&self, day: u32) -> Option<NaiveDate> {
1874
        self.with_mdf(self.mdf().with_day(day)?)
1875
    }
1876
1877
    /// Makes a new `NaiveDate` with the day of month (starting from 0) changed.
1878
    ///
1879
    /// # Errors
1880
    ///
1881
    /// Returns `None` if:
1882
    /// - The resulting date does not exist (for example `day(30)` in April).
1883
    /// - The value for `day0` is invalid.
1884
    ///
1885
    /// # Example
1886
    ///
1887
    /// ```
1888
    /// use chrono::{Datelike, NaiveDate};
1889
    ///
1890
    /// assert_eq!(
1891
    ///     NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_day0(29),
1892
    ///     Some(NaiveDate::from_ymd_opt(2015, 9, 30).unwrap())
1893
    /// );
1894
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_day0(30), None);
1895
    /// // no September 31
1896
    /// ```
1897
    #[inline]
1898
    fn with_day0(&self, day0: u32) -> Option<NaiveDate> {
1899
        let day = day0.checked_add(1)?;
1900
        self.with_mdf(self.mdf().with_day(day)?)
1901
    }
1902
1903
    /// Makes a new `NaiveDate` with the day of year (starting from 1) changed.
1904
    ///
1905
    /// # Errors
1906
    ///
1907
    /// Returns `None` if:
1908
    /// - The resulting date does not exist (`with_ordinal(366)` in a non-leap year).
1909
    /// - The value for `ordinal` is invalid.
1910
    ///
1911
    /// # Example
1912
    ///
1913
    /// ```
1914
    /// use chrono::{NaiveDate, Datelike};
1915
    ///
1916
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 1, 1).unwrap().with_ordinal(60),
1917
    ///            Some(NaiveDate::from_ymd_opt(2015, 3, 1).unwrap()));
1918
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 1, 1).unwrap().with_ordinal(366),
1919
    ///            None); // 2015 had only 365 days
1920
    ///
1921
    /// assert_eq!(NaiveDate::from_ymd_opt(2016, 1, 1).unwrap().with_ordinal(60),
1922
    ///            Some(NaiveDate::from_ymd_opt(2016, 2, 29).unwrap()));
1923
    /// assert_eq!(NaiveDate::from_ymd_opt(2016, 1, 1).unwrap().with_ordinal(366),
1924
    ///            Some(NaiveDate::from_ymd_opt(2016, 12, 31).unwrap()));
1925
    /// ```
1926
    #[inline]
1927
76
    fn with_ordinal(&self, ordinal: u32) -> Option<NaiveDate> {
1928
76
        if ordinal == 0 || ordinal > 366 {
1929
4
            return None;
1930
72
        }
1931
72
        let yof = (self.yof() & !ORDINAL_MASK) | (ordinal << 4) as i32;
1932
72
        match yof & OL_MASK <= MAX_OL {
1933
71
            true => Some(NaiveDate::from_yof(yof)),
1934
1
            false => None, // Does not exist: Ordinal 366 in a common year.
1935
        }
1936
76
    }
1937
1938
    /// Makes a new `NaiveDate` with the day of year (starting from 0) changed.
1939
    ///
1940
    /// # Errors
1941
    ///
1942
    /// Returns `None` if:
1943
    /// - The resulting date does not exist (`with_ordinal0(365)` in a non-leap year).
1944
    /// - The value for `ordinal0` is invalid.
1945
    ///
1946
    /// # Example
1947
    ///
1948
    /// ```
1949
    /// use chrono::{NaiveDate, Datelike};
1950
    ///
1951
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 1, 1).unwrap().with_ordinal0(59),
1952
    ///            Some(NaiveDate::from_ymd_opt(2015, 3, 1).unwrap()));
1953
    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 1, 1).unwrap().with_ordinal0(365),
1954
    ///            None); // 2015 had only 365 days
1955
    ///
1956
    /// assert_eq!(NaiveDate::from_ymd_opt(2016, 1, 1).unwrap().with_ordinal0(59),
1957
    ///            Some(NaiveDate::from_ymd_opt(2016, 2, 29).unwrap()));
1958
    /// assert_eq!(NaiveDate::from_ymd_opt(2016, 1, 1).unwrap().with_ordinal0(365),
1959
    ///            Some(NaiveDate::from_ymd_opt(2016, 12, 31).unwrap()));
1960
    /// ```
1961
    #[inline]
1962
    fn with_ordinal0(&self, ordinal0: u32) -> Option<NaiveDate> {
1963
        let ordinal = ordinal0.checked_add(1)?;
1964
        self.with_ordinal(ordinal)
1965
    }
1966
}
1967
1968
/// Add `TimeDelta` to `NaiveDate`.
1969
///
1970
/// This discards the fractional days in `TimeDelta`, rounding to the closest integral number of
1971
/// days towards `TimeDelta::zero()`.
1972
///
1973
/// # Panics
1974
///
1975
/// Panics if the resulting date would be out of range.
1976
/// Consider using [`NaiveDate::checked_add_signed`] to get an `Option` instead.
1977
///
1978
/// # Example
1979
///
1980
/// ```
1981
/// use chrono::{NaiveDate, TimeDelta};
1982
///
1983
/// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
1984
///
1985
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::zero(), from_ymd(2014, 1, 1));
1986
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::try_seconds(86399).unwrap(), from_ymd(2014, 1, 1));
1987
/// assert_eq!(
1988
///     from_ymd(2014, 1, 1) + TimeDelta::try_seconds(-86399).unwrap(),
1989
///     from_ymd(2014, 1, 1)
1990
/// );
1991
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::try_days(1).unwrap(), from_ymd(2014, 1, 2));
1992
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::try_days(-1).unwrap(), from_ymd(2013, 12, 31));
1993
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::try_days(364).unwrap(), from_ymd(2014, 12, 31));
1994
/// assert_eq!(
1995
///     from_ymd(2014, 1, 1) + TimeDelta::try_days(365 * 4 + 1).unwrap(),
1996
///     from_ymd(2018, 1, 1)
1997
/// );
1998
/// assert_eq!(
1999
///     from_ymd(2014, 1, 1) + TimeDelta::try_days(365 * 400 + 97).unwrap(),
2000
///     from_ymd(2414, 1, 1)
2001
/// );
2002
/// ```
2003
///
2004
/// [`NaiveDate::checked_add_signed`]: crate::NaiveDate::checked_add_signed
2005
impl Add<TimeDelta> for NaiveDate {
2006
    type Output = NaiveDate;
2007
2008
    #[inline]
2009
    #[track_caller]
2010
    fn add(self, rhs: TimeDelta) -> NaiveDate {
2011
        self.checked_add_signed(rhs).expect("`NaiveDate + TimeDelta` overflowed")
2012
    }
2013
}
2014
2015
/// Add-assign of `TimeDelta` to `NaiveDate`.
2016
///
2017
/// This discards the fractional days in `TimeDelta`, rounding to the closest integral number of days
2018
/// towards `TimeDelta::zero()`.
2019
///
2020
/// # Panics
2021
///
2022
/// Panics if the resulting date would be out of range.
2023
/// Consider using [`NaiveDate::checked_add_signed`] to get an `Option` instead.
2024
impl AddAssign<TimeDelta> for NaiveDate {
2025
    #[inline]
2026
    #[track_caller]
2027
    fn add_assign(&mut self, rhs: TimeDelta) {
2028
        *self = self.add(rhs);
2029
    }
2030
}
2031
2032
/// Add `Months` to `NaiveDate`.
2033
///
2034
/// The result will be clamped to valid days in the resulting month, see `checked_add_months` for
2035
/// details.
2036
///
2037
/// # Panics
2038
///
2039
/// Panics if the resulting date would be out of range.
2040
/// Consider using `NaiveDate::checked_add_months` to get an `Option` instead.
2041
///
2042
/// # Example
2043
///
2044
/// ```
2045
/// use chrono::{Months, NaiveDate};
2046
///
2047
/// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
2048
///
2049
/// assert_eq!(from_ymd(2014, 1, 1) + Months::new(1), from_ymd(2014, 2, 1));
2050
/// assert_eq!(from_ymd(2014, 1, 1) + Months::new(11), from_ymd(2014, 12, 1));
2051
/// assert_eq!(from_ymd(2014, 1, 1) + Months::new(12), from_ymd(2015, 1, 1));
2052
/// assert_eq!(from_ymd(2014, 1, 1) + Months::new(13), from_ymd(2015, 2, 1));
2053
/// assert_eq!(from_ymd(2014, 1, 31) + Months::new(1), from_ymd(2014, 2, 28));
2054
/// assert_eq!(from_ymd(2020, 1, 31) + Months::new(1), from_ymd(2020, 2, 29));
2055
/// ```
2056
impl Add<Months> for NaiveDate {
2057
    type Output = NaiveDate;
2058
2059
    #[track_caller]
2060
0
    fn add(self, months: Months) -> Self::Output {
2061
0
        self.checked_add_months(months).expect("`NaiveDate + Months` out of range")
2062
0
    }
2063
}
2064
2065
/// Subtract `Months` from `NaiveDate`.
2066
///
2067
/// The result will be clamped to valid days in the resulting month, see `checked_sub_months` for
2068
/// details.
2069
///
2070
/// # Panics
2071
///
2072
/// Panics if the resulting date would be out of range.
2073
/// Consider using `NaiveDate::checked_sub_months` to get an `Option` instead.
2074
///
2075
/// # Example
2076
///
2077
/// ```
2078
/// use chrono::{Months, NaiveDate};
2079
///
2080
/// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
2081
///
2082
/// assert_eq!(from_ymd(2014, 1, 1) - Months::new(11), from_ymd(2013, 2, 1));
2083
/// assert_eq!(from_ymd(2014, 1, 1) - Months::new(12), from_ymd(2013, 1, 1));
2084
/// assert_eq!(from_ymd(2014, 1, 1) - Months::new(13), from_ymd(2012, 12, 1));
2085
/// ```
2086
impl Sub<Months> for NaiveDate {
2087
    type Output = NaiveDate;
2088
2089
    #[track_caller]
2090
0
    fn sub(self, months: Months) -> Self::Output {
2091
0
        self.checked_sub_months(months).expect("`NaiveDate - Months` out of range")
2092
0
    }
2093
}
2094
2095
/// Add `Days` to `NaiveDate`.
2096
///
2097
/// # Panics
2098
///
2099
/// Panics if the resulting date would be out of range.
2100
/// Consider using `NaiveDate::checked_add_days` to get an `Option` instead.
2101
impl Add<Days> for NaiveDate {
2102
    type Output = NaiveDate;
2103
2104
    #[track_caller]
2105
0
    fn add(self, days: Days) -> Self::Output {
2106
0
        self.checked_add_days(days).expect("`NaiveDate + Days` out of range")
2107
0
    }
2108
}
2109
2110
/// Subtract `Days` from `NaiveDate`.
2111
///
2112
/// # Panics
2113
///
2114
/// Panics if the resulting date would be out of range.
2115
/// Consider using `NaiveDate::checked_sub_days` to get an `Option` instead.
2116
impl Sub<Days> for NaiveDate {
2117
    type Output = NaiveDate;
2118
2119
    #[track_caller]
2120
0
    fn sub(self, days: Days) -> Self::Output {
2121
0
        self.checked_sub_days(days).expect("`NaiveDate - Days` out of range")
2122
0
    }
2123
}
2124
2125
/// Subtract `TimeDelta` from `NaiveDate`.
2126
///
2127
/// This discards the fractional days in `TimeDelta`, rounding to the closest integral number of
2128
/// days towards `TimeDelta::zero()`.
2129
/// It is the same as the addition with a negated `TimeDelta`.
2130
///
2131
/// # Panics
2132
///
2133
/// Panics if the resulting date would be out of range.
2134
/// Consider using [`NaiveDate::checked_sub_signed`] to get an `Option` instead.
2135
///
2136
/// # Example
2137
///
2138
/// ```
2139
/// use chrono::{NaiveDate, TimeDelta};
2140
///
2141
/// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
2142
///
2143
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::zero(), from_ymd(2014, 1, 1));
2144
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::try_seconds(86399).unwrap(), from_ymd(2014, 1, 1));
2145
/// assert_eq!(
2146
///     from_ymd(2014, 1, 1) - TimeDelta::try_seconds(-86399).unwrap(),
2147
///     from_ymd(2014, 1, 1)
2148
/// );
2149
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::try_days(1).unwrap(), from_ymd(2013, 12, 31));
2150
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::try_days(-1).unwrap(), from_ymd(2014, 1, 2));
2151
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::try_days(364).unwrap(), from_ymd(2013, 1, 2));
2152
/// assert_eq!(
2153
///     from_ymd(2014, 1, 1) - TimeDelta::try_days(365 * 4 + 1).unwrap(),
2154
///     from_ymd(2010, 1, 1)
2155
/// );
2156
/// assert_eq!(
2157
///     from_ymd(2014, 1, 1) - TimeDelta::try_days(365 * 400 + 97).unwrap(),
2158
///     from_ymd(1614, 1, 1)
2159
/// );
2160
/// ```
2161
///
2162
/// [`NaiveDate::checked_sub_signed`]: crate::NaiveDate::checked_sub_signed
2163
impl Sub<TimeDelta> for NaiveDate {
2164
    type Output = NaiveDate;
2165
2166
    #[inline]
2167
    #[track_caller]
2168
    fn sub(self, rhs: TimeDelta) -> NaiveDate {
2169
        self.checked_sub_signed(rhs).expect("`NaiveDate - TimeDelta` overflowed")
2170
    }
2171
}
2172
2173
/// Subtract-assign `TimeDelta` from `NaiveDate`.
2174
///
2175
/// This discards the fractional days in `TimeDelta`, rounding to the closest integral number of
2176
/// days towards `TimeDelta::zero()`.
2177
/// It is the same as the addition with a negated `TimeDelta`.
2178
///
2179
/// # Panics
2180
///
2181
/// Panics if the resulting date would be out of range.
2182
/// Consider using [`NaiveDate::checked_sub_signed`] to get an `Option` instead.
2183
impl SubAssign<TimeDelta> for NaiveDate {
2184
    #[inline]
2185
    #[track_caller]
2186
    fn sub_assign(&mut self, rhs: TimeDelta) {
2187
        *self = self.sub(rhs);
2188
    }
2189
}
2190
2191
/// Subtracts another `NaiveDate` from the current date.
2192
/// Returns a `TimeDelta` of integral numbers.
2193
///
2194
/// This does not overflow or underflow at all,
2195
/// as all possible output fits in the range of `TimeDelta`.
2196
///
2197
/// The implementation is a wrapper around
2198
/// [`NaiveDate::signed_duration_since`](#method.signed_duration_since).
2199
///
2200
/// # Example
2201
///
2202
/// ```
2203
/// use chrono::{NaiveDate, TimeDelta};
2204
///
2205
/// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
2206
///
2207
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2014, 1, 1), TimeDelta::zero());
2208
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 12, 31), TimeDelta::try_days(1).unwrap());
2209
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2014, 1, 2), TimeDelta::try_days(-1).unwrap());
2210
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 9, 23), TimeDelta::try_days(100).unwrap());
2211
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 1, 1), TimeDelta::try_days(365).unwrap());
2212
/// assert_eq!(
2213
///     from_ymd(2014, 1, 1) - from_ymd(2010, 1, 1),
2214
///     TimeDelta::try_days(365 * 4 + 1).unwrap()
2215
/// );
2216
/// assert_eq!(
2217
///     from_ymd(2014, 1, 1) - from_ymd(1614, 1, 1),
2218
///     TimeDelta::try_days(365 * 400 + 97).unwrap()
2219
/// );
2220
/// ```
2221
impl Sub<NaiveDate> for NaiveDate {
2222
    type Output = TimeDelta;
2223
2224
    #[inline]
2225
    fn sub(self, rhs: NaiveDate) -> TimeDelta {
2226
        self.signed_duration_since(rhs)
2227
    }
2228
}
2229
2230
impl From<NaiveDateTime> for NaiveDate {
2231
0
    fn from(naive_datetime: NaiveDateTime) -> Self {
2232
0
        naive_datetime.date()
2233
0
    }
2234
}
2235
2236
/// Iterator over `NaiveDate` with a step size of one day.
2237
#[derive(Debug, Copy, Clone, Hash, PartialEq, PartialOrd, Eq, Ord)]
2238
pub struct NaiveDateDaysIterator {
2239
    value: NaiveDate,
2240
    // Exclusive upper bound. The iterator yields the half-open range `[value, end)`;
2241
    // `next` advances `value` from the front and `next_back` lowers `end` from the back.
2242
    end: NaiveDate,
2243
}
2244
2245
impl Iterator for NaiveDateDaysIterator {
2246
    type Item = NaiveDate;
2247
2248
0
    fn next(&mut self) -> Option<Self::Item> {
2249
0
        if self.value >= self.end {
2250
0
            return None;
2251
0
        }
2252
0
        let current = self.value;
2253
        // `succ_opt()` can't return `None` because `current < end <= NaiveDate::MAX`.
2254
0
        self.value = current.succ_opt()?;
2255
0
        Some(current)
2256
0
    }
2257
2258
0
    fn size_hint(&self) -> (usize, Option<usize>) {
2259
0
        let exact_size = self.end.signed_duration_since(self.value).num_days();
2260
0
        (exact_size as usize, Some(exact_size as usize))
2261
0
    }
2262
}
2263
2264
impl ExactSizeIterator for NaiveDateDaysIterator {}
2265
2266
impl DoubleEndedIterator for NaiveDateDaysIterator {
2267
0
    fn next_back(&mut self) -> Option<Self::Item> {
2268
0
        if self.value >= self.end {
2269
0
            return None;
2270
0
        }
2271
        // `pred_opt()` can't return `None` because `end > value >= NaiveDate::MIN`.
2272
0
        self.end = self.end.pred_opt()?;
2273
0
        Some(self.end)
2274
0
    }
2275
2276
0
    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2277
        // Skipping from the back in O(1) keeps `take(k).rev()` cheap despite the
2278
        // iterator spanning up to `NaiveDate::MAX`.
2279
0
        if n >= self.len() {
2280
0
            self.end = self.value;
2281
0
            return None;
2282
0
        }
2283
        // The `n`-th element from the back is `end - (n + 1)` days, which stays
2284
        // within `[value, end)` and so can't underflow past `NaiveDate::MIN`.
2285
0
        self.end = self.end.checked_sub_days(Days::new(n as u64 + 1))?;
2286
0
        Some(self.end)
2287
0
    }
2288
}
2289
2290
impl FusedIterator for NaiveDateDaysIterator {}
2291
2292
/// Iterator over `NaiveDate` with a step size of one week.
2293
#[derive(Debug, Copy, Clone, Hash, PartialEq, PartialOrd, Eq, Ord)]
2294
pub struct NaiveDateWeeksIterator {
2295
    value: NaiveDate,
2296
    // Exclusive upper bound, aligned to the weekly grid starting at `value`. The
2297
    // iterator yields `[value, end)` in weekly steps; `next` advances `value` from
2298
    // the front and `next_back` lowers `end` from the back.
2299
    end: NaiveDate,
2300
}
2301
2302
impl Iterator for NaiveDateWeeksIterator {
2303
    type Item = NaiveDate;
2304
2305
0
    fn next(&mut self) -> Option<Self::Item> {
2306
0
        if self.value >= self.end {
2307
0
            return None;
2308
0
        }
2309
0
        let current = self.value;
2310
        // Can't overflow because `current + 7 days <= end <= NaiveDate::MAX`.
2311
0
        self.value = current.checked_add_days(Days::new(7))?;
2312
0
        Some(current)
2313
0
    }
2314
2315
0
    fn size_hint(&self) -> (usize, Option<usize>) {
2316
0
        let exact_size = self.end.signed_duration_since(self.value).num_weeks();
2317
0
        (exact_size as usize, Some(exact_size as usize))
2318
0
    }
2319
}
2320
2321
impl ExactSizeIterator for NaiveDateWeeksIterator {}
2322
2323
impl DoubleEndedIterator for NaiveDateWeeksIterator {
2324
0
    fn next_back(&mut self) -> Option<Self::Item> {
2325
0
        if self.value >= self.end {
2326
0
            return None;
2327
0
        }
2328
        // Can't underflow because `end - 7 days >= value >= NaiveDate::MIN`.
2329
0
        self.end = self.end.checked_sub_days(Days::new(7))?;
2330
0
        Some(self.end)
2331
0
    }
2332
2333
0
    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2334
        // Skipping from the back in O(1) keeps `take(k).rev()` cheap despite the
2335
        // iterator spanning up to `NaiveDate::MAX`.
2336
0
        if n >= self.len() {
2337
0
            self.end = self.value;
2338
0
            return None;
2339
0
        }
2340
        // The `n`-th element from the back is `end - 7 * (n + 1)` days, which stays
2341
        // within `[value, end)` and so can't underflow past `NaiveDate::MIN`.
2342
0
        self.end = self.end.checked_sub_days(Days::new((n as u64 + 1) * 7))?;
2343
0
        Some(self.end)
2344
0
    }
2345
}
2346
2347
impl FusedIterator for NaiveDateWeeksIterator {}
2348
2349
/// The `Debug` output of the naive date `d` is the same as
2350
/// [`d.format("%Y-%m-%d")`](crate::format::strftime).
2351
///
2352
/// The string printed can be readily parsed via the `parse` method on `str`.
2353
///
2354
/// # Example
2355
///
2356
/// ```
2357
/// use chrono::NaiveDate;
2358
///
2359
/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(2015, 9, 5).unwrap()), "2015-09-05");
2360
/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(0, 1, 1).unwrap()), "0000-01-01");
2361
/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(9999, 12, 31).unwrap()), "9999-12-31");
2362
/// ```
2363
///
2364
/// ISO 8601 requires an explicit sign for years before 1 BCE or after 9999 CE.
2365
///
2366
/// ```
2367
/// # use chrono::NaiveDate;
2368
/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(-1, 1, 1).unwrap()), "-0001-01-01");
2369
/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(10000, 12, 31).unwrap()), "+10000-12-31");
2370
/// ```
2371
impl fmt::Debug for NaiveDate {
2372
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2373
        use core::fmt::Write;
2374
2375
0
        let year = self.year();
2376
0
        let mdf = self.mdf();
2377
0
        if (0..=9999).contains(&year) {
2378
0
            write_hundreds(f, (year / 100) as u8)?;
2379
0
            write_hundreds(f, (year % 100) as u8)?;
2380
        } else {
2381
            // ISO 8601 requires the explicit sign for out-of-range years
2382
0
            write!(f, "{year:+05}")?;
2383
        }
2384
2385
0
        f.write_char('-')?;
2386
0
        write_hundreds(f, mdf.month() as u8)?;
2387
0
        f.write_char('-')?;
2388
0
        write_hundreds(f, mdf.day() as u8)
2389
0
    }
2390
}
2391
2392
#[cfg(feature = "defmt")]
2393
impl defmt::Format for NaiveDate {
2394
    fn format(&self, fmt: defmt::Formatter) {
2395
        let year = self.year();
2396
        let mdf = self.mdf();
2397
        if (0..=9999).contains(&year) {
2398
            defmt::write!(fmt, "{:02}{:02}", year / 100, year % 100);
2399
        } else {
2400
            // ISO 8601 requires the explicit sign for out-of-range years
2401
            let sign = ['+', '-'][(year < 0) as usize];
2402
            defmt::write!(fmt, "{}{:05}", sign, year.abs());
2403
        }
2404
2405
        defmt::write!(fmt, "-{:02}-{:02}", mdf.month(), mdf.day());
2406
    }
2407
}
2408
2409
/// The `Display` output of the naive date `d` is the same as
2410
/// [`d.format("%Y-%m-%d")`](crate::format::strftime).
2411
///
2412
/// The string printed can be readily parsed via the `parse` method on `str`.
2413
///
2414
/// # Example
2415
///
2416
/// ```
2417
/// use chrono::NaiveDate;
2418
///
2419
/// assert_eq!(format!("{}", NaiveDate::from_ymd_opt(2015, 9, 5).unwrap()), "2015-09-05");
2420
/// assert_eq!(format!("{}", NaiveDate::from_ymd_opt(0, 1, 1).unwrap()), "0000-01-01");
2421
/// assert_eq!(format!("{}", NaiveDate::from_ymd_opt(9999, 12, 31).unwrap()), "9999-12-31");
2422
/// ```
2423
///
2424
/// ISO 8601 requires an explicit sign for years before 1 BCE or after 9999 CE.
2425
///
2426
/// ```
2427
/// # use chrono::NaiveDate;
2428
/// assert_eq!(format!("{}", NaiveDate::from_ymd_opt(-1, 1, 1).unwrap()), "-0001-01-01");
2429
/// assert_eq!(format!("{}", NaiveDate::from_ymd_opt(10000, 12, 31).unwrap()), "+10000-12-31");
2430
/// ```
2431
impl fmt::Display for NaiveDate {
2432
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2433
0
        fmt::Debug::fmt(self, f)
2434
0
    }
2435
}
2436
2437
/// Parsing a `str` into a `NaiveDate` uses the same format,
2438
/// [`%Y-%m-%d`](crate::format::strftime), as in `Debug` and `Display`.
2439
///
2440
/// # Example
2441
///
2442
/// ```
2443
/// use chrono::NaiveDate;
2444
///
2445
/// let d = NaiveDate::from_ymd_opt(2015, 9, 18).unwrap();
2446
/// assert_eq!("2015-09-18".parse::<NaiveDate>(), Ok(d));
2447
///
2448
/// let d = NaiveDate::from_ymd_opt(12345, 6, 7).unwrap();
2449
/// assert_eq!("+12345-6-7".parse::<NaiveDate>(), Ok(d));
2450
///
2451
/// assert!("foo".parse::<NaiveDate>().is_err());
2452
/// ```
2453
impl str::FromStr for NaiveDate {
2454
    type Err = ParseError;
2455
2456
0
    fn from_str(s: &str) -> ParseResult<NaiveDate> {
2457
        const ITEMS: &[Item<'static>] = &[
2458
            Item::Numeric(Numeric::Year, Pad::Zero),
2459
            Item::Space(""),
2460
            Item::Literal("-"),
2461
            Item::Numeric(Numeric::Month, Pad::Zero),
2462
            Item::Space(""),
2463
            Item::Literal("-"),
2464
            Item::Numeric(Numeric::Day, Pad::Zero),
2465
            Item::Space(""),
2466
        ];
2467
2468
0
        let mut parsed = Parsed::new();
2469
0
        parse(&mut parsed, s, ITEMS.iter())?;
2470
0
        parsed.to_naive_date()
2471
0
    }
2472
}
2473
2474
/// The default value for a NaiveDate is 1st of January 1970.
2475
///
2476
/// # Example
2477
///
2478
/// ```rust
2479
/// use chrono::NaiveDate;
2480
///
2481
/// let default_date = NaiveDate::default();
2482
/// assert_eq!(default_date, NaiveDate::from_ymd_opt(1970, 1, 1).unwrap());
2483
/// ```
2484
impl Default for NaiveDate {
2485
0
    fn default() -> Self {
2486
0
        NaiveDate::from_ymd_opt(1970, 1, 1).unwrap()
2487
0
    }
2488
}
2489
2490
1.05k
const fn cycle_to_yo(cycle: u32) -> (u32, u32) {
2491
1.05k
    let mut year_mod_400 = cycle / 365;
2492
1.05k
    let mut ordinal0 = cycle % 365;
2493
1.05k
    let delta = YEAR_DELTAS[year_mod_400 as usize] as u32;
2494
1.05k
    if ordinal0 < delta {
2495
101
        year_mod_400 -= 1;
2496
101
        ordinal0 += 365 - YEAR_DELTAS[year_mod_400 as usize] as u32;
2497
956
    } else {
2498
956
        ordinal0 -= delta;
2499
956
    }
2500
1.05k
    (year_mod_400, ordinal0 + 1)
2501
1.05k
}
2502
2503
18
const fn yo_to_cycle(year_mod_400: u32, ordinal: u32) -> u32 {
2504
18
    year_mod_400 * 365 + YEAR_DELTAS[year_mod_400 as usize] as u32 + ordinal - 1
2505
18
}
2506
2507
36
const fn div_mod_floor(val: i32, div: i32) -> (i32, i32) {
2508
36
    (val.div_euclid(div), val.rem_euclid(div))
2509
36
}
2510
2511
/// MAX_YEAR is one year less than the type is capable of representing. Internally we may sometimes
2512
/// use the headroom, notably to handle cases where the offset of a `DateTime` constructed with
2513
/// `NaiveDate::MAX` pushes it beyond the valid, representable range.
2514
pub(super) const MAX_YEAR: i32 = (i32::MAX >> 13) - 1;
2515
2516
/// MIN_YEAR is one year more than the type is capable of representing. Internally we may sometimes
2517
/// use the headroom, notably to handle cases where the offset of a `DateTime` constructed with
2518
/// `NaiveDate::MIN` pushes it beyond the valid, representable range.
2519
pub(super) const MIN_YEAR: i32 = (i32::MIN >> 13) + 1;
2520
2521
const ORDINAL_MASK: i32 = 0b1_1111_1111_0000;
2522
2523
const LEAP_YEAR_MASK: i32 = 0b1000;
2524
2525
// OL: ordinal and leap year flag.
2526
// With only these parts of the date an ordinal 366 in a common year would be encoded as
2527
// `((366 << 1) | 1) << 3`, and in a leap year as `((366 << 1) | 0) << 3`, which is less.
2528
// This allows for efficiently checking the ordinal exists depending on whether this is a leap year.
2529
const OL_MASK: i32 = ORDINAL_MASK | LEAP_YEAR_MASK;
2530
const MAX_OL: i32 = 366 << 4;
2531
2532
// Weekday of the last day in the preceding year.
2533
// Allows for quick day of week calculation from the 1-based ordinal.
2534
const WEEKDAY_FLAGS_MASK: i32 = 0b111;
2535
2536
const YEAR_FLAGS_MASK: i32 = LEAP_YEAR_MASK | WEEKDAY_FLAGS_MASK;
2537
2538
const YEAR_DELTAS: &[u8; 401] = &[
2539
    0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8,
2540
    8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14,
2541
    15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20,
2542
    21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, // 100
2543
    25, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30,
2544
    30, 31, 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35, 36, 36, 36,
2545
    36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42,
2546
    42, 43, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, 48, 48, 48,
2547
    48, 49, 49, 49, // 200
2548
    49, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54,
2549
    54, 55, 55, 55, 55, 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60,
2550
    60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63, 64, 64, 64, 64, 65, 65, 65, 65, 66, 66, 66,
2551
    66, 67, 67, 67, 67, 68, 68, 68, 68, 69, 69, 69, 69, 70, 70, 70, 70, 71, 71, 71, 71, 72, 72, 72,
2552
    72, 73, 73, 73, // 300
2553
    73, 73, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, 76, 76, 76, 76, 77, 77, 77, 77, 78, 78, 78,
2554
    78, 79, 79, 79, 79, 80, 80, 80, 80, 81, 81, 81, 81, 82, 82, 82, 82, 83, 83, 83, 83, 84, 84, 84,
2555
    84, 85, 85, 85, 85, 86, 86, 86, 86, 87, 87, 87, 87, 88, 88, 88, 88, 89, 89, 89, 89, 90, 90, 90,
2556
    90, 91, 91, 91, 91, 92, 92, 92, 92, 93, 93, 93, 93, 94, 94, 94, 94, 95, 95, 95, 95, 96, 96, 96,
2557
    96, 97, 97, 97, 97, // 400+1
2558
];
2559
2560
#[cfg(feature = "serde")]
2561
mod serde {
2562
    use super::NaiveDate;
2563
    use core::fmt;
2564
    use serde::{de, ser};
2565
2566
    // TODO not very optimized for space (binary formats would want something better)
2567
2568
    impl ser::Serialize for NaiveDate {
2569
        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2570
        where
2571
            S: ser::Serializer,
2572
        {
2573
            struct FormatWrapped<'a, D: 'a> {
2574
                inner: &'a D,
2575
            }
2576
2577
            impl<D: fmt::Debug> fmt::Display for FormatWrapped<'_, D> {
2578
                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2579
                    self.inner.fmt(f)
2580
                }
2581
            }
2582
2583
            serializer.collect_str(&FormatWrapped { inner: &self })
2584
        }
2585
    }
2586
2587
    struct NaiveDateVisitor;
2588
2589
    impl de::Visitor<'_> for NaiveDateVisitor {
2590
        type Value = NaiveDate;
2591
2592
        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
2593
            formatter.write_str("a formatted date string")
2594
        }
2595
2596
        fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
2597
        where
2598
            E: de::Error,
2599
        {
2600
            value.parse().map_err(E::custom)
2601
        }
2602
    }
2603
2604
    impl<'de> de::Deserialize<'de> for NaiveDate {
2605
        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2606
        where
2607
            D: de::Deserializer<'de>,
2608
        {
2609
            deserializer.deserialize_str(NaiveDateVisitor)
2610
        }
2611
    }
2612
2613
    #[cfg(test)]
2614
    mod tests {
2615
        use crate::NaiveDate;
2616
2617
        #[test]
2618
        fn test_serde_serialize() {
2619
            assert_eq!(
2620
                serde_json::to_string(&NaiveDate::from_ymd_opt(2014, 7, 24).unwrap()).ok(),
2621
                Some(r#""2014-07-24""#.into())
2622
            );
2623
            assert_eq!(
2624
                serde_json::to_string(&NaiveDate::from_ymd_opt(0, 1, 1).unwrap()).ok(),
2625
                Some(r#""0000-01-01""#.into())
2626
            );
2627
            assert_eq!(
2628
                serde_json::to_string(&NaiveDate::from_ymd_opt(-1, 12, 31).unwrap()).ok(),
2629
                Some(r#""-0001-12-31""#.into())
2630
            );
2631
            assert_eq!(
2632
                serde_json::to_string(&NaiveDate::MIN).ok(),
2633
                Some(r#""-262143-01-01""#.into())
2634
            );
2635
            assert_eq!(
2636
                serde_json::to_string(&NaiveDate::MAX).ok(),
2637
                Some(r#""+262142-12-31""#.into())
2638
            );
2639
        }
2640
2641
        #[test]
2642
        fn test_serde_deserialize() {
2643
            let from_str = serde_json::from_str::<NaiveDate>;
2644
2645
            assert_eq!(
2646
                from_str(r#""2016-07-08""#).ok(),
2647
                Some(NaiveDate::from_ymd_opt(2016, 7, 8).unwrap())
2648
            );
2649
            assert_eq!(
2650
                from_str(r#""2016-7-8""#).ok(),
2651
                Some(NaiveDate::from_ymd_opt(2016, 7, 8).unwrap())
2652
            );
2653
            assert_eq!(from_str(r#""+002016-07-08""#).ok(), NaiveDate::from_ymd_opt(2016, 7, 8));
2654
            assert_eq!(
2655
                from_str(r#""0000-01-01""#).ok(),
2656
                Some(NaiveDate::from_ymd_opt(0, 1, 1).unwrap())
2657
            );
2658
            assert_eq!(
2659
                from_str(r#""0-1-1""#).ok(),
2660
                Some(NaiveDate::from_ymd_opt(0, 1, 1).unwrap())
2661
            );
2662
            assert_eq!(
2663
                from_str(r#""-0001-12-31""#).ok(),
2664
                Some(NaiveDate::from_ymd_opt(-1, 12, 31).unwrap())
2665
            );
2666
            assert_eq!(from_str(r#""-262143-01-01""#).ok(), Some(NaiveDate::MIN));
2667
            assert_eq!(from_str(r#""+262142-12-31""#).ok(), Some(NaiveDate::MAX));
2668
2669
            // bad formats
2670
            assert!(from_str(r#""""#).is_err());
2671
            assert!(from_str(r#""20001231""#).is_err());
2672
            assert!(from_str(r#""2000-00-00""#).is_err());
2673
            assert!(from_str(r#""2000-02-30""#).is_err());
2674
            assert!(from_str(r#""2001-02-29""#).is_err());
2675
            assert!(from_str(r#""2002-002-28""#).is_err());
2676
            assert!(from_str(r#""yyyy-mm-dd""#).is_err());
2677
            assert!(from_str(r#"0"#).is_err());
2678
            assert!(from_str(r#"20.01"#).is_err());
2679
            let min = i32::MIN.to_string();
2680
            assert!(from_str(&min).is_err());
2681
            let max = i32::MAX.to_string();
2682
            assert!(from_str(&max).is_err());
2683
            let min = i64::MIN.to_string();
2684
            assert!(from_str(&min).is_err());
2685
            let max = i64::MAX.to_string();
2686
            assert!(from_str(&max).is_err());
2687
            assert!(from_str(r#"{}"#).is_err());
2688
        }
2689
2690
        #[test]
2691
        fn test_serde_bincode() {
2692
            // Bincode is relevant to test separately from JSON because
2693
            // it is not self-describing.
2694
            use bincode::{deserialize, serialize};
2695
2696
            let d = NaiveDate::from_ymd_opt(2014, 7, 24).unwrap();
2697
            let encoded = serialize(&d).unwrap();
2698
            let decoded: NaiveDate = deserialize(&encoded).unwrap();
2699
            assert_eq!(d, decoded);
2700
        }
2701
    }
2702
}