chrono/naive/date/
mod.rs

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