chrono/naive/
date.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#[cfg(feature = "alloc")]
7use core::borrow::Borrow;
8use core::iter::FusedIterator;
9use core::ops::{Add, AddAssign, RangeInclusive, Sub, SubAssign};
10use core::{fmt, str};
11
12#[cfg(any(feature = "rkyv", feature = "rkyv-16", feature = "rkyv-32", feature = "rkyv-64"))]
13use rkyv::{Archive, Deserialize, Serialize};
14
15/// L10n locales.
16#[cfg(all(feature = "unstable-locales", feature = "alloc"))]
17use pure_rust_locales::Locale;
18
19#[cfg(feature = "alloc")]
20use crate::format::DelayedFormat;
21use crate::format::{
22    parse, parse_and_remainder, write_hundreds, Item, Numeric, Pad, ParseError, ParseResult,
23    Parsed, StrftimeItems,
24};
25use crate::month::Months;
26use crate::naive::{IsoWeek, NaiveDateTime, NaiveTime};
27use crate::{expect, try_opt};
28use crate::{Datelike, TimeDelta, Weekday};
29
30use super::internals::{self, DateImpl, Mdf, Of, YearFlags};
31use super::isoweek;
32
33const MAX_YEAR: i32 = internals::MAX_YEAR;
34const MIN_YEAR: i32 = internals::MIN_YEAR;
35
36/// A week represented by a [`NaiveDate`] and a [`Weekday`] which is the first
37/// day of the week.
38#[derive(Debug)]
39pub struct NaiveWeek {
40    date: NaiveDate,
41    start: Weekday,
42}
43
44impl NaiveWeek {
45    /// Returns a date representing the first day of the week.
46    ///
47    /// # Panics
48    ///
49    /// Panics if the first day of the week happens to fall just out of range of `NaiveDate`
50    /// (more than ca. 262,000 years away from common era).
51    ///
52    /// # Examples
53    ///
54    /// ```
55    /// use chrono::{NaiveDate, Weekday};
56    ///
57    /// let date = NaiveDate::from_ymd_opt(2022, 4, 18).unwrap();
58    /// let week = date.week(Weekday::Mon);
59    /// assert!(week.first_day() <= date);
60    /// ```
61    #[inline]
62    #[must_use]
63    pub const fn first_day(&self) -> NaiveDate {
64        let start = self.start.num_days_from_monday() as i32;
65        let ref_day = self.date.weekday().num_days_from_monday() as i32;
66        // Calculate the number of days to subtract from `self.date`.
67        // Do not construct an intermediate date beyond `self.date`, because that may be out of
68        // range if `date` is close to `NaiveDate::MAX`.
69        let days = start - ref_day - if start > ref_day { 7 } else { 0 };
70        expect!(self.date.add_days(days), "first weekday out of range for `NaiveDate`")
71    }
72
73    /// Returns a date representing the last day of the week.
74    ///
75    /// # Panics
76    ///
77    /// Panics if the last day of the week happens to fall just out of range of `NaiveDate`
78    /// (more than ca. 262,000 years away from common era).
79    ///
80    /// # Examples
81    ///
82    /// ```
83    /// use chrono::{NaiveDate, Weekday};
84    ///
85    /// let date = NaiveDate::from_ymd_opt(2022, 4, 18).unwrap();
86    /// let week = date.week(Weekday::Mon);
87    /// assert!(week.last_day() >= date);
88    /// ```
89    #[inline]
90    #[must_use]
91    pub const fn last_day(&self) -> NaiveDate {
92        let end = self.start.pred().num_days_from_monday() as i32;
93        let ref_day = self.date.weekday().num_days_from_monday() as i32;
94        // Calculate the number of days to add to `self.date`.
95        // Do not construct an intermediate date before `self.date` (like with `first_day()`),
96        // because that may be out of range if `date` is close to `NaiveDate::MIN`.
97        let days = end - ref_day + if end < ref_day { 7 } else { 0 };
98        expect!(self.date.add_days(days), "last weekday out of range for `NaiveDate`")
99    }
100
101    /// Returns a [`RangeInclusive<T>`] representing the whole week bounded by
102    /// [first_day](NaiveWeek::first_day) and [last_day](NaiveWeek::last_day) functions.
103    ///
104    /// # Panics
105    ///
106    /// Panics if the either the first or last day of the week happens to fall just out of range of
107    /// `NaiveDate` (more than ca. 262,000 years away from common era).
108    ///
109    /// # Examples
110    ///
111    /// ```
112    /// use chrono::{NaiveDate, Weekday};
113    ///
114    /// let date = NaiveDate::from_ymd_opt(2022, 4, 18).unwrap();
115    /// let week = date.week(Weekday::Mon);
116    /// let days = week.days();
117    /// assert!(days.contains(&date));
118    /// ```
119    #[inline]
120    #[must_use]
121    pub const fn days(&self) -> RangeInclusive<NaiveDate> {
122        self.first_day()..=self.last_day()
123    }
124}
125
126/// A duration in calendar days.
127///
128/// This is useful because when using `TimeDelta` it is possible that adding `TimeDelta::days(1)`
129/// doesn't increment the day value as expected due to it being a fixed number of seconds. This
130/// difference applies only when dealing with `DateTime<TimeZone>` data types and in other cases
131/// `TimeDelta::days(n)` and `Days::new(n)` are equivalent.
132#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
133pub struct Days(pub(crate) u64);
134
135impl Days {
136    /// Construct a new `Days` from a number of days
137    pub const fn new(num: u64) -> Self {
138        Self(num)
139    }
140}
141
142/// ISO 8601 calendar date without timezone.
143/// Allows for every [proleptic Gregorian date] from Jan 1, 262145 BCE to Dec 31, 262143 CE.
144/// Also supports the conversion from ISO 8601 ordinal and week date.
145///
146/// # Calendar Date
147///
148/// The ISO 8601 **calendar date** follows the proleptic Gregorian calendar.
149/// It is like a normal civil calendar but note some slight differences:
150///
151/// * Dates before the Gregorian calendar's inception in 1582 are defined via the extrapolation.
152///   Be careful, as historical dates are often noted in the Julian calendar and others
153///   and the transition to Gregorian may differ across countries (as late as early 20C).
154///
155///   (Some example: Both Shakespeare from Britain and Cervantes from Spain seemingly died
156///   on the same calendar date---April 23, 1616---but in the different calendar.
157///   Britain used the Julian calendar at that time, so Shakespeare's death is later.)
158///
159/// * ISO 8601 calendars has the year 0, which is 1 BCE (a year before 1 CE).
160///   If you need a typical BCE/BC and CE/AD notation for year numbers,
161///   use the [`Datelike::year_ce`] method.
162///
163/// # Week Date
164///
165/// The ISO 8601 **week date** is a triple of year number, week number
166/// and [day of the week](Weekday) with the following rules:
167///
168/// * A week consists of Monday through Sunday, and is always numbered within some year.
169///   The week number ranges from 1 to 52 or 53 depending on the year.
170///
171/// * The week 1 of given year is defined as the first week containing January 4 of that year,
172///   or equivalently, the first week containing four or more days in that year.
173///
174/// * The year number in the week date may *not* correspond to the actual Gregorian year.
175///   For example, January 3, 2016 (Sunday) was on the last (53rd) week of 2015.
176///
177/// Chrono's date types default to the ISO 8601 [calendar date](#calendar-date), but
178/// [`Datelike::iso_week`] and [`Datelike::weekday`] methods can be used to get the corresponding
179/// week date.
180///
181/// # Ordinal Date
182///
183/// The ISO 8601 **ordinal date** is a pair of year number and day of the year ("ordinal").
184/// The ordinal number ranges from 1 to 365 or 366 depending on the year.
185/// The year number is the same as that of the [calendar date](#calendar-date).
186///
187/// This is currently the internal format of Chrono's date types.
188///
189/// [proleptic Gregorian date]: crate::NaiveDate#calendar-date
190#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Copy, Clone)]
191#[cfg_attr(
192    any(feature = "rkyv", feature = "rkyv-16", feature = "rkyv-32", feature = "rkyv-64"),
193    derive(Archive, Deserialize, Serialize),
194    archive(compare(PartialEq, PartialOrd)),
195    archive_attr(derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash))
196)]
197#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
198pub struct NaiveDate {
199    ymdf: DateImpl, // (year << 13) | of
200}
201
202/// The minimum possible `NaiveDate` (January 1, 262145 BCE).
203#[deprecated(since = "0.4.20", note = "Use NaiveDate::MIN instead")]
204pub const MIN_DATE: NaiveDate = NaiveDate::MIN;
205/// The maximum possible `NaiveDate` (December 31, 262143 CE).
206#[deprecated(since = "0.4.20", note = "Use NaiveDate::MAX instead")]
207pub const MAX_DATE: NaiveDate = NaiveDate::MAX;
208
209#[cfg(all(feature = "arbitrary", feature = "std"))]
210impl arbitrary::Arbitrary<'_> for NaiveDate {
211    fn arbitrary(u: &mut arbitrary::Unstructured) -> arbitrary::Result<NaiveDate> {
212        let year = u.int_in_range(MIN_YEAR..=MAX_YEAR)?;
213        let max_days = YearFlags::from_year(year).ndays();
214        let ord = u.int_in_range(1..=max_days)?;
215        NaiveDate::from_yo_opt(year, ord).ok_or(arbitrary::Error::IncorrectFormat)
216    }
217}
218
219impl NaiveDate {
220    pub(crate) fn weeks_from(&self, day: Weekday) -> i32 {
221        (self.ordinal() as i32 - self.weekday().num_days_from(day) as i32 + 6) / 7
222    }
223
224    /// Makes a new `NaiveDate` from year, ordinal and flags.
225    /// Does not check whether the flags are correct for the provided year.
226    const fn from_ordinal_and_flags(
227        year: i32,
228        ordinal: u32,
229        flags: YearFlags,
230    ) -> Option<NaiveDate> {
231        if year < MIN_YEAR || year > MAX_YEAR {
232            return None; // Out-of-range
233        }
234        debug_assert!(YearFlags::from_year(year).0 == flags.0);
235        match Of::new(ordinal, flags) {
236            Some(of) => Some(NaiveDate { ymdf: (year << 13) | (of.inner() as DateImpl) }),
237            None => None, // Invalid: Ordinal outside of the nr of days in a year with those flags.
238        }
239    }
240
241    /// Makes a new `NaiveDate` from year and packed month-day-flags.
242    /// Does not check whether the flags are correct for the provided year.
243    const fn from_mdf(year: i32, mdf: Mdf) -> Option<NaiveDate> {
244        if year < MIN_YEAR || year > MAX_YEAR {
245            return None; // Out-of-range
246        }
247        match mdf.to_of() {
248            Some(of) => Some(NaiveDate { ymdf: (year << 13) | (of.inner() as DateImpl) }),
249            None => None, // Non-existing date
250        }
251    }
252
253    /// Makes a new `NaiveDate` from the [calendar date](#calendar-date)
254    /// (year, month and day).
255    ///
256    /// # Panics
257    ///
258    /// Panics if the specified calendar day does not exist, on invalid values for `month` or `day`,
259    /// or if `year` is out of range for `NaiveDate`.
260    #[deprecated(since = "0.4.23", note = "use `from_ymd_opt()` instead")]
261    #[must_use]
262    pub const fn from_ymd(year: i32, month: u32, day: u32) -> NaiveDate {
263        expect!(NaiveDate::from_ymd_opt(year, month, day), "invalid or out-of-range date")
264    }
265
266    /// Makes a new `NaiveDate` from the [calendar date](#calendar-date)
267    /// (year, month and day).
268    ///
269    /// # Errors
270    ///
271    /// Returns `None` if:
272    /// - The specified calendar day does not exist (for example 2023-04-31).
273    /// - The value for `month` or `day` is invalid.
274    /// - `year` is out of range for `NaiveDate`.
275    ///
276    /// # Example
277    ///
278    /// ```
279    /// use chrono::NaiveDate;
280    ///
281    /// let from_ymd_opt = NaiveDate::from_ymd_opt;
282    ///
283    /// assert!(from_ymd_opt(2015, 3, 14).is_some());
284    /// assert!(from_ymd_opt(2015, 0, 14).is_none());
285    /// assert!(from_ymd_opt(2015, 2, 29).is_none());
286    /// assert!(from_ymd_opt(-4, 2, 29).is_some()); // 5 BCE is a leap year
287    /// assert!(from_ymd_opt(400000, 1, 1).is_none());
288    /// assert!(from_ymd_opt(-400000, 1, 1).is_none());
289    /// ```
290    #[must_use]
291    pub const fn from_ymd_opt(year: i32, month: u32, day: u32) -> Option<NaiveDate> {
292        let flags = YearFlags::from_year(year);
293
294        if let Some(mdf) = Mdf::new(month, day, flags) {
295            NaiveDate::from_mdf(year, mdf)
296        } else {
297            None
298        }
299    }
300
301    /// Makes a new `NaiveDate` from the [ordinal date](#ordinal-date)
302    /// (year and day of the year).
303    ///
304    /// # Panics
305    ///
306    /// Panics if the specified ordinal day does not exist, on invalid values for `ordinal`, or if
307    /// `year` is out of range for `NaiveDate`.
308    #[deprecated(since = "0.4.23", note = "use `from_yo_opt()` instead")]
309    #[must_use]
310    pub const fn from_yo(year: i32, ordinal: u32) -> NaiveDate {
311        expect!(NaiveDate::from_yo_opt(year, ordinal), "invalid or out-of-range date")
312    }
313
314    /// Makes a new `NaiveDate` from the [ordinal date](#ordinal-date)
315    /// (year and day of the year).
316    ///
317    /// # Errors
318    ///
319    /// Returns `None` if:
320    /// - The specified ordinal day does not exist (for example 2023-366).
321    /// - The value for `ordinal` is invalid (for example: `0`, `400`).
322    /// - `year` is out of range for `NaiveDate`.
323    ///
324    /// # Example
325    ///
326    /// ```
327    /// use chrono::NaiveDate;
328    ///
329    /// let from_yo_opt = NaiveDate::from_yo_opt;
330    ///
331    /// assert!(from_yo_opt(2015, 100).is_some());
332    /// assert!(from_yo_opt(2015, 0).is_none());
333    /// assert!(from_yo_opt(2015, 365).is_some());
334    /// assert!(from_yo_opt(2015, 366).is_none());
335    /// assert!(from_yo_opt(-4, 366).is_some()); // 5 BCE is a leap year
336    /// assert!(from_yo_opt(400000, 1).is_none());
337    /// assert!(from_yo_opt(-400000, 1).is_none());
338    /// ```
339    #[must_use]
340    pub const fn from_yo_opt(year: i32, ordinal: u32) -> Option<NaiveDate> {
341        let flags = YearFlags::from_year(year);
342        NaiveDate::from_ordinal_and_flags(year, ordinal, flags)
343    }
344
345    /// Makes a new `NaiveDate` from the [ISO week date](#week-date)
346    /// (year, week number and day of the week).
347    /// The resulting `NaiveDate` may have a different year from the input year.
348    ///
349    /// # Panics
350    ///
351    /// Panics if the specified week does not exist in that year, on invalid values for `week`, or
352    /// if the resulting date is out of range for `NaiveDate`.
353    #[deprecated(since = "0.4.23", note = "use `from_isoywd_opt()` instead")]
354    #[must_use]
355    pub const fn from_isoywd(year: i32, week: u32, weekday: Weekday) -> NaiveDate {
356        expect!(NaiveDate::from_isoywd_opt(year, week, weekday), "invalid or out-of-range date")
357    }
358
359    /// Makes a new `NaiveDate` from the [ISO week date](#week-date)
360    /// (year, week number and day of the week).
361    /// The resulting `NaiveDate` may have a different year from the input year.
362    ///
363    /// # Errors
364    ///
365    /// Returns `None` if:
366    /// - The specified week does not exist in that year (for example 2023 week 53).
367    /// - The value for `week` is invalid (for example: `0`, `60`).
368    /// - If the resulting date is out of range for `NaiveDate`.
369    ///
370    /// # Example
371    ///
372    /// ```
373    /// use chrono::{NaiveDate, Weekday};
374    ///
375    /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
376    /// let from_isoywd_opt = NaiveDate::from_isoywd_opt;
377    ///
378    /// assert_eq!(from_isoywd_opt(2015, 0, Weekday::Sun), None);
379    /// assert_eq!(from_isoywd_opt(2015, 10, Weekday::Sun), Some(from_ymd(2015, 3, 8)));
380    /// assert_eq!(from_isoywd_opt(2015, 30, Weekday::Mon), Some(from_ymd(2015, 7, 20)));
381    /// assert_eq!(from_isoywd_opt(2015, 60, Weekday::Mon), None);
382    ///
383    /// assert_eq!(from_isoywd_opt(400000, 10, Weekday::Fri), None);
384    /// assert_eq!(from_isoywd_opt(-400000, 10, Weekday::Sat), None);
385    /// ```
386    ///
387    /// The year number of ISO week date may differ from that of the calendar date.
388    ///
389    /// ```
390    /// # use chrono::{NaiveDate, Weekday};
391    /// # let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
392    /// # let from_isoywd_opt = NaiveDate::from_isoywd_opt;
393    /// //           Mo Tu We Th Fr Sa Su
394    /// // 2014-W52  22 23 24 25 26 27 28    has 4+ days of new year,
395    /// // 2015-W01  29 30 31  1  2  3  4 <- so this is the first week
396    /// assert_eq!(from_isoywd_opt(2014, 52, Weekday::Sun), Some(from_ymd(2014, 12, 28)));
397    /// assert_eq!(from_isoywd_opt(2014, 53, Weekday::Mon), None);
398    /// assert_eq!(from_isoywd_opt(2015, 1, Weekday::Mon), Some(from_ymd(2014, 12, 29)));
399    ///
400    /// // 2015-W52  21 22 23 24 25 26 27    has 4+ days of old year,
401    /// // 2015-W53  28 29 30 31  1  2  3 <- so this is the last week
402    /// // 2016-W01   4  5  6  7  8  9 10
403    /// assert_eq!(from_isoywd_opt(2015, 52, Weekday::Sun), Some(from_ymd(2015, 12, 27)));
404    /// assert_eq!(from_isoywd_opt(2015, 53, Weekday::Sun), Some(from_ymd(2016, 1, 3)));
405    /// assert_eq!(from_isoywd_opt(2015, 54, Weekday::Mon), None);
406    /// assert_eq!(from_isoywd_opt(2016, 1, Weekday::Mon), Some(from_ymd(2016, 1, 4)));
407    /// ```
408    #[must_use]
409    pub const fn from_isoywd_opt(year: i32, week: u32, weekday: Weekday) -> Option<NaiveDate> {
410        let flags = YearFlags::from_year(year);
411        let nweeks = flags.nisoweeks();
412        if 1 <= week && week <= nweeks {
413            // ordinal = week ordinal - delta
414            let weekord = week * 7 + weekday as u32;
415            let delta = flags.isoweek_delta();
416            if weekord <= delta {
417                // ordinal < 1, previous year
418                let prevflags = YearFlags::from_year(year - 1);
419                NaiveDate::from_ordinal_and_flags(
420                    year - 1,
421                    weekord + prevflags.ndays() - delta,
422                    prevflags,
423                )
424            } else {
425                let ordinal = weekord - delta;
426                let ndays = flags.ndays();
427                if ordinal <= ndays {
428                    // this year
429                    NaiveDate::from_ordinal_and_flags(year, ordinal, flags)
430                } else {
431                    // ordinal > ndays, next year
432                    let nextflags = YearFlags::from_year(year + 1);
433                    NaiveDate::from_ordinal_and_flags(year + 1, ordinal - ndays, nextflags)
434                }
435            }
436        } else {
437            None
438        }
439    }
440
441    /// Makes a new `NaiveDate` from a day's number in the proleptic Gregorian calendar, with
442    /// January 1, 1 being day 1.
443    ///
444    /// # Panics
445    ///
446    /// Panics if the date is out of range.
447    #[deprecated(since = "0.4.23", note = "use `from_num_days_from_ce_opt()` instead")]
448    #[inline]
449    #[must_use]
450    pub const fn from_num_days_from_ce(days: i32) -> NaiveDate {
451        expect!(NaiveDate::from_num_days_from_ce_opt(days), "out-of-range date")
452    }
453
454    /// Makes a new `NaiveDate` from a day's number in the proleptic Gregorian calendar, with
455    /// January 1, 1 being day 1.
456    ///
457    /// # Errors
458    ///
459    /// Returns `None` if the date is out of range.
460    ///
461    /// # Example
462    ///
463    /// ```
464    /// use chrono::NaiveDate;
465    ///
466    /// let from_ndays_opt = NaiveDate::from_num_days_from_ce_opt;
467    /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
468    ///
469    /// assert_eq!(from_ndays_opt(730_000),      Some(from_ymd(1999, 9, 3)));
470    /// assert_eq!(from_ndays_opt(1),            Some(from_ymd(1, 1, 1)));
471    /// assert_eq!(from_ndays_opt(0),            Some(from_ymd(0, 12, 31)));
472    /// assert_eq!(from_ndays_opt(-1),           Some(from_ymd(0, 12, 30)));
473    /// assert_eq!(from_ndays_opt(100_000_000),  None);
474    /// assert_eq!(from_ndays_opt(-100_000_000), None);
475    /// ```
476    #[must_use]
477    pub const fn from_num_days_from_ce_opt(days: i32) -> Option<NaiveDate> {
478        let days = try_opt!(days.checked_add(365)); // make December 31, 1 BCE equal to day 0
479        let year_div_400 = days.div_euclid(146_097);
480        let cycle = days.rem_euclid(146_097);
481        let (year_mod_400, ordinal) = internals::cycle_to_yo(cycle as u32);
482        let flags = YearFlags::from_year_mod_400(year_mod_400 as i32);
483        NaiveDate::from_ordinal_and_flags(year_div_400 * 400 + year_mod_400 as i32, ordinal, flags)
484    }
485
486    /// Makes a new `NaiveDate` by counting the number of occurrences of a particular day-of-week
487    /// since the beginning of the given month. For instance, if you want the 2nd Friday of March
488    /// 2017, you would use `NaiveDate::from_weekday_of_month(2017, 3, Weekday::Fri, 2)`.
489    ///
490    /// `n` is 1-indexed.
491    ///
492    /// # Panics
493    ///
494    /// Panics if the specified day does not exist in that month, on invalid values for `month` or
495    /// `n`, or if `year` is out of range for `NaiveDate`.
496    #[deprecated(since = "0.4.23", note = "use `from_weekday_of_month_opt()` instead")]
497    #[must_use]
498    pub const fn from_weekday_of_month(
499        year: i32,
500        month: u32,
501        weekday: Weekday,
502        n: u8,
503    ) -> NaiveDate {
504        expect!(NaiveDate::from_weekday_of_month_opt(year, month, weekday, n), "out-of-range date")
505    }
506
507    /// Makes a new `NaiveDate` by counting the number of occurrences of a particular day-of-week
508    /// since the beginning of the given month. For instance, if you want the 2nd Friday of March
509    /// 2017, you would use `NaiveDate::from_weekday_of_month(2017, 3, Weekday::Fri, 2)`.
510    ///
511    /// `n` is 1-indexed.
512    ///
513    /// # Errors
514    ///
515    /// Returns `None` if:
516    /// - The specified day does not exist in that month (for example the 5th Monday of Apr. 2023).
517    /// - The value for `month` or `n` is invalid.
518    /// - `year` is out of range for `NaiveDate`.
519    ///
520    /// # Example
521    ///
522    /// ```
523    /// use chrono::{NaiveDate, Weekday};
524    /// assert_eq!(NaiveDate::from_weekday_of_month_opt(2017, 3, Weekday::Fri, 2),
525    ///            NaiveDate::from_ymd_opt(2017, 3, 10))
526    /// ```
527    #[must_use]
528    pub const fn from_weekday_of_month_opt(
529        year: i32,
530        month: u32,
531        weekday: Weekday,
532        n: u8,
533    ) -> Option<NaiveDate> {
534        if n == 0 {
535            return None;
536        }
537        let first = try_opt!(NaiveDate::from_ymd_opt(year, month, 1)).weekday();
538        let first_to_dow = (7 + weekday.number_from_monday() - first.number_from_monday()) % 7;
539        let day = (n - 1) as u32 * 7 + first_to_dow + 1;
540        NaiveDate::from_ymd_opt(year, month, day)
541    }
542
543    /// Parses a string with the specified format string and returns a new `NaiveDate`.
544    /// See the [`format::strftime` module](crate::format::strftime)
545    /// on the supported escape sequences.
546    ///
547    /// # Example
548    ///
549    /// ```
550    /// use chrono::NaiveDate;
551    ///
552    /// let parse_from_str = NaiveDate::parse_from_str;
553    ///
554    /// assert_eq!(parse_from_str("2015-09-05", "%Y-%m-%d"),
555    ///            Ok(NaiveDate::from_ymd_opt(2015, 9, 5).unwrap()));
556    /// assert_eq!(parse_from_str("5sep2015", "%d%b%Y"),
557    ///            Ok(NaiveDate::from_ymd_opt(2015, 9, 5).unwrap()));
558    /// ```
559    ///
560    /// Time and offset is ignored for the purpose of parsing.
561    ///
562    /// ```
563    /// # use chrono::NaiveDate;
564    /// # let parse_from_str = NaiveDate::parse_from_str;
565    /// assert_eq!(parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
566    ///            Ok(NaiveDate::from_ymd_opt(2014, 5, 17).unwrap()));
567    /// ```
568    ///
569    /// Out-of-bound dates or insufficient fields are errors.
570    ///
571    /// ```
572    /// # use chrono::NaiveDate;
573    /// # let parse_from_str = NaiveDate::parse_from_str;
574    /// assert!(parse_from_str("2015/9", "%Y/%m").is_err());
575    /// assert!(parse_from_str("2015/9/31", "%Y/%m/%d").is_err());
576    /// ```
577    ///
578    /// All parsed fields should be consistent to each other, otherwise it's an error.
579    ///
580    /// ```
581    /// # use chrono::NaiveDate;
582    /// # let parse_from_str = NaiveDate::parse_from_str;
583    /// assert!(parse_from_str("Sat, 09 Aug 2013", "%a, %d %b %Y").is_err());
584    /// ```
585    pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveDate> {
586        let mut parsed = Parsed::new();
587        parse(&mut parsed, s, StrftimeItems::new(fmt))?;
588        parsed.to_naive_date()
589    }
590
591    /// Parses a string from a user-specified format into a new `NaiveDate` value, and a slice with
592    /// the remaining portion of the string.
593    /// See the [`format::strftime` module](crate::format::strftime)
594    /// on the supported escape sequences.
595    ///
596    /// Similar to [`parse_from_str`](#method.parse_from_str).
597    ///
598    /// # Example
599    ///
600    /// ```rust
601    /// # use chrono::{NaiveDate};
602    /// let (date, remainder) = NaiveDate::parse_and_remainder(
603    ///     "2015-02-18 trailing text", "%Y-%m-%d").unwrap();
604    /// assert_eq!(date, NaiveDate::from_ymd_opt(2015, 2, 18).unwrap());
605    /// assert_eq!(remainder, " trailing text");
606    /// ```
607    pub fn parse_and_remainder<'a>(s: &'a str, fmt: &str) -> ParseResult<(NaiveDate, &'a str)> {
608        let mut parsed = Parsed::new();
609        let remainder = parse_and_remainder(&mut parsed, s, StrftimeItems::new(fmt))?;
610        parsed.to_naive_date().map(|d| (d, remainder))
611    }
612
613    /// Add a duration in [`Months`] to the date
614    ///
615    /// Uses the last day of the month if the day does not exist in the resulting month.
616    ///
617    /// # Errors
618    ///
619    /// Returns `None` if the resulting date would be out of range.
620    ///
621    /// # Example
622    ///
623    /// ```
624    /// # use chrono::{NaiveDate, Months};
625    /// assert_eq!(
626    ///     NaiveDate::from_ymd_opt(2022, 2, 20).unwrap().checked_add_months(Months::new(6)),
627    ///     Some(NaiveDate::from_ymd_opt(2022, 8, 20).unwrap())
628    /// );
629    /// assert_eq!(
630    ///     NaiveDate::from_ymd_opt(2022, 7, 31).unwrap().checked_add_months(Months::new(2)),
631    ///     Some(NaiveDate::from_ymd_opt(2022, 9, 30).unwrap())
632    /// );
633    /// ```
634    #[must_use]
635    pub const fn checked_add_months(self, months: Months) -> Option<Self> {
636        if months.0 == 0 {
637            return Some(self);
638        }
639
640        match months.0 <= core::i32::MAX as u32 {
641            true => self.diff_months(months.0 as i32),
642            false => None,
643        }
644    }
645
646    /// Subtract a duration in [`Months`] from the date
647    ///
648    /// Uses the last day of the month if the day does not exist in the resulting month.
649    ///
650    /// # Errors
651    ///
652    /// Returns `None` if the resulting date would be out of range.
653    ///
654    /// # Example
655    ///
656    /// ```
657    /// # use chrono::{NaiveDate, Months};
658    /// assert_eq!(
659    ///     NaiveDate::from_ymd_opt(2022, 2, 20).unwrap().checked_sub_months(Months::new(6)),
660    ///     Some(NaiveDate::from_ymd_opt(2021, 8, 20).unwrap())
661    /// );
662    ///
663    /// assert_eq!(
664    ///     NaiveDate::from_ymd_opt(2014, 1, 1).unwrap()
665    ///         .checked_sub_months(Months::new(core::i32::MAX as u32 + 1)),
666    ///     None
667    /// );
668    /// ```
669    #[must_use]
670    pub const fn checked_sub_months(self, months: Months) -> Option<Self> {
671        if months.0 == 0 {
672            return Some(self);
673        }
674
675        // Copy `i32::MAX` here so we don't have to do a complicated cast
676        match months.0 <= 2_147_483_647 {
677            true => self.diff_months(-(months.0 as i32)),
678            false => None,
679        }
680    }
681
682    const fn diff_months(self, months: i32) -> Option<Self> {
683        let (years, left) = ((months / 12), (months % 12));
684
685        // Determine new year (without taking months into account for now
686
687        let year = if (years > 0 && years > (MAX_YEAR - self.year()))
688            || (years < 0 && years < (MIN_YEAR - self.year()))
689        {
690            return None;
691        } else {
692            self.year() + years
693        };
694
695        // Determine new month
696
697        let month = self.month() as i32 + left;
698        let (year, month) = if month <= 0 {
699            if year == MIN_YEAR {
700                return None;
701            }
702
703            (year - 1, month + 12)
704        } else if month > 12 {
705            if year == MAX_YEAR {
706                return None;
707            }
708
709            (year + 1, month - 12)
710        } else {
711            (year, month)
712        };
713
714        // Clamp original day in case new month is shorter
715
716        let flags = YearFlags::from_year(year);
717        let feb_days = if flags.ndays() == 366 { 29 } else { 28 };
718        let days = [31, feb_days, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
719        let day_max = days[(month - 1) as usize];
720        let mut day = self.day();
721        if day > day_max {
722            day = day_max;
723        };
724
725        NaiveDate::from_mdf(year, try_opt!(Mdf::new(month as u32, day, flags)))
726    }
727
728    /// Add a duration in [`Days`] to the date
729    ///
730    /// # Errors
731    ///
732    /// Returns `None` if the resulting date would be out of range.
733    ///
734    /// # Example
735    ///
736    /// ```
737    /// # use chrono::{NaiveDate, Days};
738    /// assert_eq!(
739    ///     NaiveDate::from_ymd_opt(2022, 2, 20).unwrap().checked_add_days(Days::new(9)),
740    ///     Some(NaiveDate::from_ymd_opt(2022, 3, 1).unwrap())
741    /// );
742    /// assert_eq!(
743    ///     NaiveDate::from_ymd_opt(2022, 7, 31).unwrap().checked_add_days(Days::new(2)),
744    ///     Some(NaiveDate::from_ymd_opt(2022, 8, 2).unwrap())
745    /// );
746    /// assert_eq!(
747    ///     NaiveDate::from_ymd_opt(2022, 7, 31).unwrap().checked_add_days(Days::new(1000000000000)),
748    ///     None
749    /// );
750    /// ```
751    #[must_use]
752    pub const fn checked_add_days(self, days: Days) -> Option<Self> {
753        match days.0 <= i32::MAX as u64 {
754            true => self.add_days(days.0 as i32),
755            false => None,
756        }
757    }
758
759    /// Subtract a duration in [`Days`] from the date
760    ///
761    /// # Errors
762    ///
763    /// Returns `None` if the resulting date would be out of range.
764    ///
765    /// # Example
766    ///
767    /// ```
768    /// # use chrono::{NaiveDate, Days};
769    /// assert_eq!(
770    ///     NaiveDate::from_ymd_opt(2022, 2, 20).unwrap().checked_sub_days(Days::new(6)),
771    ///     Some(NaiveDate::from_ymd_opt(2022, 2, 14).unwrap())
772    /// );
773    /// assert_eq!(
774    ///     NaiveDate::from_ymd_opt(2022, 2, 20).unwrap().checked_sub_days(Days::new(1000000000000)),
775    ///     None
776    /// );
777    /// ```
778    #[must_use]
779    pub const fn checked_sub_days(self, days: Days) -> Option<Self> {
780        match days.0 <= i32::MAX as u64 {
781            true => self.add_days(-(days.0 as i32)),
782            false => None,
783        }
784    }
785
786    /// Add a duration of `i32` days to the date.
787    pub(crate) const fn add_days(self, days: i32) -> Option<Self> {
788        // fast path if the result is within the same year
789        const ORDINAL_MASK: i32 = 0b1_1111_1111_0000;
790        if let Some(ordinal) = ((self.ymdf & ORDINAL_MASK) >> 4).checked_add(days) {
791            if ordinal > 0 && ordinal <= 365 {
792                let year_and_flags = self.ymdf & !ORDINAL_MASK;
793                return Some(NaiveDate { ymdf: year_and_flags | (ordinal << 4) });
794            }
795        }
796        // do the full check
797        let year = self.year();
798        let (mut year_div_400, year_mod_400) = div_mod_floor(year, 400);
799        let cycle = internals::yo_to_cycle(year_mod_400 as u32, self.of().ordinal());
800        let cycle = try_opt!((cycle as i32).checked_add(days));
801        let (cycle_div_400y, cycle) = div_mod_floor(cycle, 146_097);
802        year_div_400 += cycle_div_400y;
803
804        let (year_mod_400, ordinal) = internals::cycle_to_yo(cycle as u32);
805        let flags = YearFlags::from_year_mod_400(year_mod_400 as i32);
806        NaiveDate::from_ordinal_and_flags(year_div_400 * 400 + year_mod_400 as i32, ordinal, flags)
807    }
808
809    /// Makes a new `NaiveDateTime` from the current date and given `NaiveTime`.
810    ///
811    /// # Example
812    ///
813    /// ```
814    /// use chrono::{NaiveDate, NaiveTime, NaiveDateTime};
815    ///
816    /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
817    /// let t = NaiveTime::from_hms_milli_opt(12, 34, 56, 789).unwrap();
818    ///
819    /// let dt: NaiveDateTime = d.and_time(t);
820    /// assert_eq!(dt.date(), d);
821    /// assert_eq!(dt.time(), t);
822    /// ```
823    #[inline]
824    #[must_use]
825    pub const fn and_time(&self, time: NaiveTime) -> NaiveDateTime {
826        NaiveDateTime::new(*self, time)
827    }
828
829    /// Makes a new `NaiveDateTime` from the current date, hour, minute and second.
830    ///
831    /// No [leap second](./struct.NaiveTime.html#leap-second-handling) is allowed here;
832    /// use `NaiveDate::and_hms_*` methods with a subsecond parameter instead.
833    ///
834    /// # Panics
835    ///
836    /// Panics on invalid hour, minute and/or second.
837    #[deprecated(since = "0.4.23", note = "use `and_hms_opt()` instead")]
838    #[inline]
839    #[must_use]
840    pub const fn and_hms(&self, hour: u32, min: u32, sec: u32) -> NaiveDateTime {
841        expect!(self.and_hms_opt(hour, min, sec), "invalid time")
842    }
843
844    /// Makes a new `NaiveDateTime` from the current date, hour, minute and second.
845    ///
846    /// No [leap second](./struct.NaiveTime.html#leap-second-handling) is allowed here;
847    /// use `NaiveDate::and_hms_*_opt` methods with a subsecond parameter instead.
848    ///
849    /// # Errors
850    ///
851    /// Returns `None` on invalid hour, minute and/or second.
852    ///
853    /// # Example
854    ///
855    /// ```
856    /// use chrono::NaiveDate;
857    ///
858    /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
859    /// assert!(d.and_hms_opt(12, 34, 56).is_some());
860    /// assert!(d.and_hms_opt(12, 34, 60).is_none()); // use `and_hms_milli_opt` instead
861    /// assert!(d.and_hms_opt(12, 60, 56).is_none());
862    /// assert!(d.and_hms_opt(24, 34, 56).is_none());
863    /// ```
864    #[inline]
865    #[must_use]
866    pub const fn and_hms_opt(&self, hour: u32, min: u32, sec: u32) -> Option<NaiveDateTime> {
867        let time = try_opt!(NaiveTime::from_hms_opt(hour, min, sec));
868        Some(self.and_time(time))
869    }
870
871    /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and millisecond.
872    ///
873    /// The millisecond part is allowed to exceed 1,000,000,000 in order to represent a [leap second](
874    /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`.
875    ///
876    /// # Panics
877    ///
878    /// Panics on invalid hour, minute, second and/or millisecond.
879    #[deprecated(since = "0.4.23", note = "use `and_hms_milli_opt()` instead")]
880    #[inline]
881    #[must_use]
882    pub const fn and_hms_milli(&self, hour: u32, min: u32, sec: u32, milli: u32) -> NaiveDateTime {
883        expect!(self.and_hms_milli_opt(hour, min, sec, milli), "invalid time")
884    }
885
886    /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and millisecond.
887    ///
888    /// The millisecond part is allowed to exceed 1,000,000,000 in order to represent a [leap second](
889    /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`.
890    ///
891    /// # Errors
892    ///
893    /// Returns `None` on invalid hour, minute, second and/or millisecond.
894    ///
895    /// # Example
896    ///
897    /// ```
898    /// use chrono::NaiveDate;
899    ///
900    /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
901    /// assert!(d.and_hms_milli_opt(12, 34, 56,   789).is_some());
902    /// assert!(d.and_hms_milli_opt(12, 34, 59, 1_789).is_some()); // leap second
903    /// assert!(d.and_hms_milli_opt(12, 34, 59, 2_789).is_none());
904    /// assert!(d.and_hms_milli_opt(12, 34, 60,   789).is_none());
905    /// assert!(d.and_hms_milli_opt(12, 60, 56,   789).is_none());
906    /// assert!(d.and_hms_milli_opt(24, 34, 56,   789).is_none());
907    /// ```
908    #[inline]
909    #[must_use]
910    pub const fn and_hms_milli_opt(
911        &self,
912        hour: u32,
913        min: u32,
914        sec: u32,
915        milli: u32,
916    ) -> Option<NaiveDateTime> {
917        let time = try_opt!(NaiveTime::from_hms_milli_opt(hour, min, sec, milli));
918        Some(self.and_time(time))
919    }
920
921    /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and microsecond.
922    ///
923    /// The microsecond part is allowed to exceed 1,000,000,000 in order to represent a [leap second](
924    /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`.
925    ///
926    /// # Panics
927    ///
928    /// Panics on invalid hour, minute, second and/or microsecond.
929    ///
930    /// # Example
931    ///
932    /// ```
933    /// use chrono::{NaiveDate, NaiveDateTime, Datelike, Timelike, Weekday};
934    ///
935    /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
936    ///
937    /// let dt: NaiveDateTime = d.and_hms_micro_opt(12, 34, 56, 789_012).unwrap();
938    /// assert_eq!(dt.year(), 2015);
939    /// assert_eq!(dt.weekday(), Weekday::Wed);
940    /// assert_eq!(dt.second(), 56);
941    /// assert_eq!(dt.nanosecond(), 789_012_000);
942    /// ```
943    #[deprecated(since = "0.4.23", note = "use `and_hms_micro_opt()` instead")]
944    #[inline]
945    #[must_use]
946    pub const fn and_hms_micro(&self, hour: u32, min: u32, sec: u32, micro: u32) -> NaiveDateTime {
947        expect!(self.and_hms_micro_opt(hour, min, sec, micro), "invalid time")
948    }
949
950    /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and microsecond.
951    ///
952    /// The microsecond part is allowed to exceed 1,000,000,000 in order to represent a [leap second](
953    /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`.
954    ///
955    /// # Errors
956    ///
957    /// Returns `None` on invalid hour, minute, second and/or microsecond.
958    ///
959    /// # Example
960    ///
961    /// ```
962    /// use chrono::NaiveDate;
963    ///
964    /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
965    /// assert!(d.and_hms_micro_opt(12, 34, 56,   789_012).is_some());
966    /// assert!(d.and_hms_micro_opt(12, 34, 59, 1_789_012).is_some()); // leap second
967    /// assert!(d.and_hms_micro_opt(12, 34, 59, 2_789_012).is_none());
968    /// assert!(d.and_hms_micro_opt(12, 34, 60,   789_012).is_none());
969    /// assert!(d.and_hms_micro_opt(12, 60, 56,   789_012).is_none());
970    /// assert!(d.and_hms_micro_opt(24, 34, 56,   789_012).is_none());
971    /// ```
972    #[inline]
973    #[must_use]
974    pub const fn and_hms_micro_opt(
975        &self,
976        hour: u32,
977        min: u32,
978        sec: u32,
979        micro: u32,
980    ) -> Option<NaiveDateTime> {
981        let time = try_opt!(NaiveTime::from_hms_micro_opt(hour, min, sec, micro));
982        Some(self.and_time(time))
983    }
984
985    /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and nanosecond.
986    ///
987    /// The nanosecond part is allowed to exceed 1,000,000,000 in order to represent a [leap second](
988    /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`.
989    ///
990    /// # Panics
991    ///
992    /// Panics on invalid hour, minute, second and/or nanosecond.
993    #[deprecated(since = "0.4.23", note = "use `and_hms_nano_opt()` instead")]
994    #[inline]
995    #[must_use]
996    pub const fn and_hms_nano(&self, hour: u32, min: u32, sec: u32, nano: u32) -> NaiveDateTime {
997        expect!(self.and_hms_nano_opt(hour, min, sec, nano), "invalid time")
998    }
999
1000    /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and nanosecond.
1001    ///
1002    /// The nanosecond part is allowed to exceed 1,000,000,000 in order to represent a [leap second](
1003    /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`.
1004    ///
1005    /// # Errors
1006    ///
1007    /// Returns `None` on invalid hour, minute, second and/or nanosecond.
1008    ///
1009    /// # Example
1010    ///
1011    /// ```
1012    /// use chrono::NaiveDate;
1013    ///
1014    /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
1015    /// assert!(d.and_hms_nano_opt(12, 34, 56,   789_012_345).is_some());
1016    /// assert!(d.and_hms_nano_opt(12, 34, 59, 1_789_012_345).is_some()); // leap second
1017    /// assert!(d.and_hms_nano_opt(12, 34, 59, 2_789_012_345).is_none());
1018    /// assert!(d.and_hms_nano_opt(12, 34, 60,   789_012_345).is_none());
1019    /// assert!(d.and_hms_nano_opt(12, 60, 56,   789_012_345).is_none());
1020    /// assert!(d.and_hms_nano_opt(24, 34, 56,   789_012_345).is_none());
1021    /// ```
1022    #[inline]
1023    #[must_use]
1024    pub const fn and_hms_nano_opt(
1025        &self,
1026        hour: u32,
1027        min: u32,
1028        sec: u32,
1029        nano: u32,
1030    ) -> Option<NaiveDateTime> {
1031        let time = try_opt!(NaiveTime::from_hms_nano_opt(hour, min, sec, nano));
1032        Some(self.and_time(time))
1033    }
1034
1035    /// Returns the packed month-day-flags.
1036    #[inline]
1037    const fn mdf(&self) -> Mdf {
1038        self.of().to_mdf()
1039    }
1040
1041    /// Returns the packed ordinal-flags.
1042    #[inline]
1043    const fn of(&self) -> Of {
1044        Of::from_date_impl(self.ymdf)
1045    }
1046
1047    /// Makes a new `NaiveDate` with the packed month-day-flags changed.
1048    ///
1049    /// Returns `None` when the resulting `NaiveDate` would be invalid.
1050    #[inline]
1051    const fn with_mdf(&self, mdf: Mdf) -> Option<NaiveDate> {
1052        Some(self.with_of(try_opt!(mdf.to_of())))
1053    }
1054
1055    /// Makes a new `NaiveDate` with the packed ordinal-flags changed.
1056    ///
1057    /// Returns `None` when the resulting `NaiveDate` would be invalid.
1058    /// Does not check if the year flags match the year.
1059    #[inline]
1060    const fn with_of(&self, of: Of) -> NaiveDate {
1061        NaiveDate { ymdf: (self.ymdf & !0b1_1111_1111_1111) | of.inner() as DateImpl }
1062    }
1063
1064    /// Makes a new `NaiveDate` for the next calendar date.
1065    ///
1066    /// # Panics
1067    ///
1068    /// Panics when `self` is the last representable date.
1069    #[deprecated(since = "0.4.23", note = "use `succ_opt()` instead")]
1070    #[inline]
1071    #[must_use]
1072    pub const fn succ(&self) -> NaiveDate {
1073        expect!(self.succ_opt(), "out of bound")
1074    }
1075
1076    /// Makes a new `NaiveDate` for the next calendar date.
1077    ///
1078    /// # Errors
1079    ///
1080    /// Returns `None` when `self` is the last representable date.
1081    ///
1082    /// # Example
1083    ///
1084    /// ```
1085    /// use chrono::NaiveDate;
1086    ///
1087    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 6, 3).unwrap().succ_opt(),
1088    ///            Some(NaiveDate::from_ymd_opt(2015, 6, 4).unwrap()));
1089    /// assert_eq!(NaiveDate::MAX.succ_opt(), None);
1090    /// ```
1091    #[inline]
1092    #[must_use]
1093    pub const fn succ_opt(&self) -> Option<NaiveDate> {
1094        match self.of().succ() {
1095            Some(of) => Some(self.with_of(of)),
1096            None => NaiveDate::from_ymd_opt(self.year() + 1, 1, 1),
1097        }
1098    }
1099
1100    /// Makes a new `NaiveDate` for the previous calendar date.
1101    ///
1102    /// # Panics
1103    ///
1104    /// Panics when `self` is the first representable date.
1105    #[deprecated(since = "0.4.23", note = "use `pred_opt()` instead")]
1106    #[inline]
1107    #[must_use]
1108    pub const fn pred(&self) -> NaiveDate {
1109        expect!(self.pred_opt(), "out of bound")
1110    }
1111
1112    /// Makes a new `NaiveDate` for the previous calendar date.
1113    ///
1114    /// # Errors
1115    ///
1116    /// Returns `None` when `self` is the first representable date.
1117    ///
1118    /// # Example
1119    ///
1120    /// ```
1121    /// use chrono::NaiveDate;
1122    ///
1123    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 6, 3).unwrap().pred_opt(),
1124    ///            Some(NaiveDate::from_ymd_opt(2015, 6, 2).unwrap()));
1125    /// assert_eq!(NaiveDate::MIN.pred_opt(), None);
1126    /// ```
1127    #[inline]
1128    #[must_use]
1129    pub const fn pred_opt(&self) -> Option<NaiveDate> {
1130        match self.of().pred() {
1131            Some(of) => Some(self.with_of(of)),
1132            None => NaiveDate::from_ymd_opt(self.year() - 1, 12, 31),
1133        }
1134    }
1135
1136    /// Adds the number of whole days in the given `TimeDelta` to the current date.
1137    ///
1138    /// # Errors
1139    ///
1140    /// Returns `None` if the resulting date would be out of range.
1141    ///
1142    /// # Example
1143    ///
1144    /// ```
1145    /// use chrono::{TimeDelta, NaiveDate};
1146    ///
1147    /// let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
1148    /// assert_eq!(d.checked_add_signed(TimeDelta::days(40)),
1149    ///            Some(NaiveDate::from_ymd_opt(2015, 10, 15).unwrap()));
1150    /// assert_eq!(d.checked_add_signed(TimeDelta::days(-40)),
1151    ///            Some(NaiveDate::from_ymd_opt(2015, 7, 27).unwrap()));
1152    /// assert_eq!(d.checked_add_signed(TimeDelta::days(1_000_000_000)), None);
1153    /// assert_eq!(d.checked_add_signed(TimeDelta::days(-1_000_000_000)), None);
1154    /// assert_eq!(NaiveDate::MAX.checked_add_signed(TimeDelta::days(1)), None);
1155    /// ```
1156    #[must_use]
1157    pub const fn checked_add_signed(self, rhs: TimeDelta) -> Option<NaiveDate> {
1158        let days = rhs.num_days();
1159        if days < i32::MIN as i64 || days > i32::MAX as i64 {
1160            return None;
1161        }
1162        self.add_days(days as i32)
1163    }
1164
1165    /// Subtracts the number of whole days in the given `TimeDelta` from the current date.
1166    ///
1167    /// # Errors
1168    ///
1169    /// Returns `None` if the resulting date would be out of range.
1170    ///
1171    /// # Example
1172    ///
1173    /// ```
1174    /// use chrono::{TimeDelta, NaiveDate};
1175    ///
1176    /// let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
1177    /// assert_eq!(d.checked_sub_signed(TimeDelta::days(40)),
1178    ///            Some(NaiveDate::from_ymd_opt(2015, 7, 27).unwrap()));
1179    /// assert_eq!(d.checked_sub_signed(TimeDelta::days(-40)),
1180    ///            Some(NaiveDate::from_ymd_opt(2015, 10, 15).unwrap()));
1181    /// assert_eq!(d.checked_sub_signed(TimeDelta::days(1_000_000_000)), None);
1182    /// assert_eq!(d.checked_sub_signed(TimeDelta::days(-1_000_000_000)), None);
1183    /// assert_eq!(NaiveDate::MIN.checked_sub_signed(TimeDelta::days(1)), None);
1184    /// ```
1185    #[must_use]
1186    pub const fn checked_sub_signed(self, rhs: TimeDelta) -> Option<NaiveDate> {
1187        let days = -rhs.num_days();
1188        if days < i32::MIN as i64 || days > i32::MAX as i64 {
1189            return None;
1190        }
1191        self.add_days(days as i32)
1192    }
1193
1194    /// Subtracts another `NaiveDate` from the current date.
1195    /// Returns a `TimeDelta` of integral numbers.
1196    ///
1197    /// This does not overflow or underflow at all,
1198    /// as all possible output fits in the range of `TimeDelta`.
1199    ///
1200    /// # Example
1201    ///
1202    /// ```
1203    /// use chrono::{TimeDelta, NaiveDate};
1204    ///
1205    /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
1206    /// let since = NaiveDate::signed_duration_since;
1207    ///
1208    /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2014, 1, 1)), TimeDelta::zero());
1209    /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2013, 12, 31)), TimeDelta::days(1));
1210    /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2014, 1, 2)), TimeDelta::days(-1));
1211    /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2013, 9, 23)), TimeDelta::days(100));
1212    /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2013, 1, 1)), TimeDelta::days(365));
1213    /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2010, 1, 1)), TimeDelta::days(365*4 + 1));
1214    /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(1614, 1, 1)), TimeDelta::days(365*400 + 97));
1215    /// ```
1216    #[must_use]
1217    pub const fn signed_duration_since(self, rhs: NaiveDate) -> TimeDelta {
1218        let year1 = self.year();
1219        let year2 = rhs.year();
1220        let (year1_div_400, year1_mod_400) = div_mod_floor(year1, 400);
1221        let (year2_div_400, year2_mod_400) = div_mod_floor(year2, 400);
1222        let cycle1 = internals::yo_to_cycle(year1_mod_400 as u32, self.of().ordinal()) as i64;
1223        let cycle2 = internals::yo_to_cycle(year2_mod_400 as u32, rhs.of().ordinal()) as i64;
1224        TimeDelta::days((year1_div_400 as i64 - year2_div_400 as i64) * 146_097 + (cycle1 - cycle2))
1225    }
1226
1227    /// Returns the number of whole years from the given `base` until `self`.
1228    ///
1229    /// # Errors
1230    ///
1231    /// Returns `None` if `base < self`.
1232    #[must_use]
1233    pub const fn years_since(&self, base: Self) -> Option<u32> {
1234        let mut years = self.year() - base.year();
1235        // Comparing tuples is not (yet) possible in const context. Instead we combine month and
1236        // day into one `u32` for easy comparison.
1237        if (self.month() << 5 | self.day()) < (base.month() << 5 | base.day()) {
1238            years -= 1;
1239        }
1240
1241        match years >= 0 {
1242            true => Some(years as u32),
1243            false => None,
1244        }
1245    }
1246
1247    /// Formats the date with the specified formatting items.
1248    /// Otherwise it is the same as the ordinary `format` method.
1249    ///
1250    /// The `Iterator` of items should be `Clone`able,
1251    /// since the resulting `DelayedFormat` value may be formatted multiple times.
1252    ///
1253    /// # Example
1254    ///
1255    /// ```
1256    /// use chrono::NaiveDate;
1257    /// use chrono::format::strftime::StrftimeItems;
1258    ///
1259    /// let fmt = StrftimeItems::new("%Y-%m-%d");
1260    /// let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
1261    /// assert_eq!(d.format_with_items(fmt.clone()).to_string(), "2015-09-05");
1262    /// assert_eq!(d.format("%Y-%m-%d").to_string(),             "2015-09-05");
1263    /// ```
1264    ///
1265    /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
1266    ///
1267    /// ```
1268    /// # use chrono::NaiveDate;
1269    /// # use chrono::format::strftime::StrftimeItems;
1270    /// # let fmt = StrftimeItems::new("%Y-%m-%d").clone();
1271    /// # let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
1272    /// assert_eq!(format!("{}", d.format_with_items(fmt)), "2015-09-05");
1273    /// ```
1274    #[cfg(feature = "alloc")]
1275    #[inline]
1276    #[must_use]
1277    pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat<I>
1278    where
1279        I: Iterator<Item = B> + Clone,
1280        B: Borrow<Item<'a>>,
1281    {
1282        DelayedFormat::new(Some(*self), None, items)
1283    }
1284
1285    /// Formats the date with the specified format string.
1286    /// See the [`format::strftime` module](crate::format::strftime)
1287    /// on the supported escape sequences.
1288    ///
1289    /// This returns a `DelayedFormat`,
1290    /// which gets converted to a string only when actual formatting happens.
1291    /// You may use the `to_string` method to get a `String`,
1292    /// or just feed it into `print!` and other formatting macros.
1293    /// (In this way it avoids the redundant memory allocation.)
1294    ///
1295    /// A wrong format string does *not* issue an error immediately.
1296    /// Rather, converting or formatting the `DelayedFormat` fails.
1297    /// You are recommended to immediately use `DelayedFormat` for this reason.
1298    ///
1299    /// # Example
1300    ///
1301    /// ```
1302    /// use chrono::NaiveDate;
1303    ///
1304    /// let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
1305    /// assert_eq!(d.format("%Y-%m-%d").to_string(), "2015-09-05");
1306    /// assert_eq!(d.format("%A, %-d %B, %C%y").to_string(), "Saturday, 5 September, 2015");
1307    /// ```
1308    ///
1309    /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
1310    ///
1311    /// ```
1312    /// # use chrono::NaiveDate;
1313    /// # let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
1314    /// assert_eq!(format!("{}", d.format("%Y-%m-%d")), "2015-09-05");
1315    /// assert_eq!(format!("{}", d.format("%A, %-d %B, %C%y")), "Saturday, 5 September, 2015");
1316    /// ```
1317    #[cfg(feature = "alloc")]
1318    #[inline]
1319    #[must_use]
1320    pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
1321        self.format_with_items(StrftimeItems::new(fmt))
1322    }
1323
1324    /// Formats the date with the specified formatting items and locale.
1325    #[cfg(all(feature = "unstable-locales", feature = "alloc"))]
1326    #[inline]
1327    #[must_use]
1328    pub fn format_localized_with_items<'a, I, B>(
1329        &self,
1330        items: I,
1331        locale: Locale,
1332    ) -> DelayedFormat<I>
1333    where
1334        I: Iterator<Item = B> + Clone,
1335        B: Borrow<Item<'a>>,
1336    {
1337        DelayedFormat::new_with_locale(Some(*self), None, items, locale)
1338    }
1339
1340    /// Formats the date with the specified format string and locale.
1341    ///
1342    /// See the [`crate::format::strftime`] module on the supported escape
1343    /// sequences.
1344    #[cfg(all(feature = "unstable-locales", feature = "alloc"))]
1345    #[inline]
1346    #[must_use]
1347    pub fn format_localized<'a>(
1348        &self,
1349        fmt: &'a str,
1350        locale: Locale,
1351    ) -> DelayedFormat<StrftimeItems<'a>> {
1352        self.format_localized_with_items(StrftimeItems::new_with_locale(fmt, locale), locale)
1353    }
1354
1355    /// Returns an iterator that steps by days across all representable dates.
1356    ///
1357    /// # Example
1358    ///
1359    /// ```
1360    /// # use chrono::NaiveDate;
1361    ///
1362    /// let expected = [
1363    ///     NaiveDate::from_ymd_opt(2016, 2, 27).unwrap(),
1364    ///     NaiveDate::from_ymd_opt(2016, 2, 28).unwrap(),
1365    ///     NaiveDate::from_ymd_opt(2016, 2, 29).unwrap(),
1366    ///     NaiveDate::from_ymd_opt(2016, 3, 1).unwrap(),
1367    /// ];
1368    ///
1369    /// let mut count = 0;
1370    /// for (idx, d) in NaiveDate::from_ymd_opt(2016, 2, 27).unwrap().iter_days().take(4).enumerate() {
1371    ///    assert_eq!(d, expected[idx]);
1372    ///    count += 1;
1373    /// }
1374    /// assert_eq!(count, 4);
1375    ///
1376    /// for d in NaiveDate::from_ymd_opt(2016, 3, 1).unwrap().iter_days().rev().take(4) {
1377    ///     count -= 1;
1378    ///     assert_eq!(d, expected[count]);
1379    /// }
1380    /// ```
1381    #[inline]
1382    pub const fn iter_days(&self) -> NaiveDateDaysIterator {
1383        NaiveDateDaysIterator { value: *self }
1384    }
1385
1386    /// Returns an iterator that steps by weeks across all representable dates.
1387    ///
1388    /// # Example
1389    ///
1390    /// ```
1391    /// # use chrono::NaiveDate;
1392    ///
1393    /// let expected = [
1394    ///     NaiveDate::from_ymd_opt(2016, 2, 27).unwrap(),
1395    ///     NaiveDate::from_ymd_opt(2016, 3, 5).unwrap(),
1396    ///     NaiveDate::from_ymd_opt(2016, 3, 12).unwrap(),
1397    ///     NaiveDate::from_ymd_opt(2016, 3, 19).unwrap(),
1398    /// ];
1399    ///
1400    /// let mut count = 0;
1401    /// for (idx, d) in NaiveDate::from_ymd_opt(2016, 2, 27).unwrap().iter_weeks().take(4).enumerate() {
1402    ///    assert_eq!(d, expected[idx]);
1403    ///    count += 1;
1404    /// }
1405    /// assert_eq!(count, 4);
1406    ///
1407    /// for d in NaiveDate::from_ymd_opt(2016, 3, 19).unwrap().iter_weeks().rev().take(4) {
1408    ///     count -= 1;
1409    ///     assert_eq!(d, expected[count]);
1410    /// }
1411    /// ```
1412    #[inline]
1413    pub const fn iter_weeks(&self) -> NaiveDateWeeksIterator {
1414        NaiveDateWeeksIterator { value: *self }
1415    }
1416
1417    /// Returns the [`NaiveWeek`] that the date belongs to, starting with the [`Weekday`]
1418    /// specified.
1419    #[inline]
1420    pub const fn week(&self, start: Weekday) -> NaiveWeek {
1421        NaiveWeek { date: *self, start }
1422    }
1423
1424    /// Returns `true` if this is a leap year.
1425    ///
1426    /// ```
1427    /// # use chrono::NaiveDate;
1428    /// assert_eq!(NaiveDate::from_ymd_opt(2000, 1, 1).unwrap().leap_year(), true);
1429    /// assert_eq!(NaiveDate::from_ymd_opt(2001, 1, 1).unwrap().leap_year(), false);
1430    /// assert_eq!(NaiveDate::from_ymd_opt(2002, 1, 1).unwrap().leap_year(), false);
1431    /// assert_eq!(NaiveDate::from_ymd_opt(2003, 1, 1).unwrap().leap_year(), false);
1432    /// assert_eq!(NaiveDate::from_ymd_opt(2004, 1, 1).unwrap().leap_year(), true);
1433    /// assert_eq!(NaiveDate::from_ymd_opt(2100, 1, 1).unwrap().leap_year(), false);
1434    /// ```
1435    pub const fn leap_year(&self) -> bool {
1436        self.ymdf & (0b1000) == 0
1437    }
1438
1439    // This duplicates `Datelike::year()`, because trait methods can't be const yet.
1440    #[inline]
1441    const fn year(&self) -> i32 {
1442        self.ymdf >> 13
1443    }
1444
1445    /// Returns the day of year starting from 1.
1446    // This duplicates `Datelike::ordinal()`, because trait methods can't be const yet.
1447    #[inline]
1448    const fn ordinal(&self) -> u32 {
1449        self.of().ordinal()
1450    }
1451
1452    // This duplicates `Datelike::month()`, because trait methods can't be const yet.
1453    #[inline]
1454    const fn month(&self) -> u32 {
1455        self.mdf().month()
1456    }
1457
1458    // This duplicates `Datelike::day()`, because trait methods can't be const yet.
1459    #[inline]
1460    const fn day(&self) -> u32 {
1461        self.mdf().day()
1462    }
1463
1464    // This duplicates `Datelike::weekday()`, because trait methods can't be const yet.
1465    #[inline]
1466    const fn weekday(&self) -> Weekday {
1467        self.of().weekday()
1468    }
1469
1470    /// Counts the days in the proleptic Gregorian calendar, with January 1, Year 1 (CE) as day 1.
1471    // This duplicates `Datelike::num_days_from_ce()`, because trait methods can't be const yet.
1472    pub(crate) const fn num_days_from_ce(&self) -> i32 {
1473        // we know this wouldn't overflow since year is limited to 1/2^13 of i32's full range.
1474        let mut year = self.year() - 1;
1475        let mut ndays = 0;
1476        if year < 0 {
1477            let excess = 1 + (-year) / 400;
1478            year += excess * 400;
1479            ndays -= excess * 146_097;
1480        }
1481        let div_100 = year / 100;
1482        ndays += ((year * 1461) >> 2) - div_100 + (div_100 >> 2);
1483        ndays + self.ordinal() as i32
1484    }
1485
1486    /// The minimum possible `NaiveDate` (January 1, 262144 BCE).
1487    pub const MIN: NaiveDate = NaiveDate { ymdf: (MIN_YEAR << 13) | (1 << 4) | 0o12 /*D*/ };
1488    /// The maximum possible `NaiveDate` (December 31, 262142 CE).
1489    pub const MAX: NaiveDate = NaiveDate { ymdf: (MAX_YEAR << 13) | (365 << 4) | 0o16 /*G*/ };
1490
1491    /// One day before the minimum possible `NaiveDate` (December 31, 262145 BCE).
1492    pub(crate) const BEFORE_MIN: NaiveDate =
1493        NaiveDate { ymdf: ((MIN_YEAR - 1) << 13) | (366 << 4) | 0o07 /*FE*/ };
1494    /// One day after the maximum possible `NaiveDate` (January 1, 262143 CE).
1495    pub(crate) const AFTER_MAX: NaiveDate =
1496        NaiveDate { ymdf: ((MAX_YEAR + 1) << 13) | (1 << 4) | 0o17 /*F*/ };
1497}
1498
1499impl Datelike for NaiveDate {
1500    /// Returns the year number in the [calendar date](#calendar-date).
1501    ///
1502    /// # Example
1503    ///
1504    /// ```
1505    /// use chrono::{NaiveDate, Datelike};
1506    ///
1507    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().year(), 2015);
1508    /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().year(), -308); // 309 BCE
1509    /// ```
1510    #[inline]
1511    fn year(&self) -> i32 {
1512        self.year()
1513    }
1514
1515    /// Returns the month number starting from 1.
1516    ///
1517    /// The return value ranges from 1 to 12.
1518    ///
1519    /// # Example
1520    ///
1521    /// ```
1522    /// use chrono::{NaiveDate, Datelike};
1523    ///
1524    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().month(), 9);
1525    /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().month(), 3);
1526    /// ```
1527    #[inline]
1528    fn month(&self) -> u32 {
1529        self.month()
1530    }
1531
1532    /// Returns the month number starting from 0.
1533    ///
1534    /// The return value ranges from 0 to 11.
1535    ///
1536    /// # Example
1537    ///
1538    /// ```
1539    /// use chrono::{NaiveDate, Datelike};
1540    ///
1541    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().month0(), 8);
1542    /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().month0(), 2);
1543    /// ```
1544    #[inline]
1545    fn month0(&self) -> u32 {
1546        self.month() - 1
1547    }
1548
1549    /// Returns the day of month starting from 1.
1550    ///
1551    /// The return value ranges from 1 to 31. (The last day of month differs by months.)
1552    ///
1553    /// # Example
1554    ///
1555    /// ```
1556    /// use chrono::{NaiveDate, Datelike};
1557    ///
1558    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().day(), 8);
1559    /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().day(), 14);
1560    /// ```
1561    ///
1562    /// Combined with [`NaiveDate::pred_opt`](#method.pred_opt),
1563    /// one can determine the number of days in a particular month.
1564    /// (Note that this panics when `year` is out of range.)
1565    ///
1566    /// ```
1567    /// use chrono::{NaiveDate, Datelike};
1568    ///
1569    /// fn ndays_in_month(year: i32, month: u32) -> u32 {
1570    ///     // the first day of the next month...
1571    ///     let (y, m) = if month == 12 { (year + 1, 1) } else { (year, month + 1) };
1572    ///     let d = NaiveDate::from_ymd_opt(y, m, 1).unwrap();
1573    ///
1574    ///     // ...is preceded by the last day of the original month
1575    ///     d.pred_opt().unwrap().day()
1576    /// }
1577    ///
1578    /// assert_eq!(ndays_in_month(2015, 8), 31);
1579    /// assert_eq!(ndays_in_month(2015, 9), 30);
1580    /// assert_eq!(ndays_in_month(2015, 12), 31);
1581    /// assert_eq!(ndays_in_month(2016, 2), 29);
1582    /// assert_eq!(ndays_in_month(2017, 2), 28);
1583    /// ```
1584    #[inline]
1585    fn day(&self) -> u32 {
1586        self.day()
1587    }
1588
1589    /// Returns the day of month starting from 0.
1590    ///
1591    /// The return value ranges from 0 to 30. (The last day of month differs by months.)
1592    ///
1593    /// # Example
1594    ///
1595    /// ```
1596    /// use chrono::{NaiveDate, Datelike};
1597    ///
1598    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().day0(), 7);
1599    /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().day0(), 13);
1600    /// ```
1601    #[inline]
1602    fn day0(&self) -> u32 {
1603        self.mdf().day() - 1
1604    }
1605
1606    /// Returns the day of year starting from 1.
1607    ///
1608    /// The return value ranges from 1 to 366. (The last day of year differs by years.)
1609    ///
1610    /// # Example
1611    ///
1612    /// ```
1613    /// use chrono::{NaiveDate, Datelike};
1614    ///
1615    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().ordinal(), 251);
1616    /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().ordinal(), 74);
1617    /// ```
1618    ///
1619    /// Combined with [`NaiveDate::pred_opt`](#method.pred_opt),
1620    /// one can determine the number of days in a particular year.
1621    /// (Note that this panics when `year` is out of range.)
1622    ///
1623    /// ```
1624    /// use chrono::{NaiveDate, Datelike};
1625    ///
1626    /// fn ndays_in_year(year: i32) -> u32 {
1627    ///     // the first day of the next year...
1628    ///     let d = NaiveDate::from_ymd_opt(year + 1, 1, 1).unwrap();
1629    ///
1630    ///     // ...is preceded by the last day of the original year
1631    ///     d.pred_opt().unwrap().ordinal()
1632    /// }
1633    ///
1634    /// assert_eq!(ndays_in_year(2015), 365);
1635    /// assert_eq!(ndays_in_year(2016), 366);
1636    /// assert_eq!(ndays_in_year(2017), 365);
1637    /// assert_eq!(ndays_in_year(2000), 366);
1638    /// assert_eq!(ndays_in_year(2100), 365);
1639    /// ```
1640    #[inline]
1641    fn ordinal(&self) -> u32 {
1642        self.of().ordinal()
1643    }
1644
1645    /// Returns the day of year starting from 0.
1646    ///
1647    /// The return value ranges from 0 to 365. (The last day of year differs by years.)
1648    ///
1649    /// # Example
1650    ///
1651    /// ```
1652    /// use chrono::{NaiveDate, Datelike};
1653    ///
1654    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().ordinal0(), 250);
1655    /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().ordinal0(), 73);
1656    /// ```
1657    #[inline]
1658    fn ordinal0(&self) -> u32 {
1659        self.of().ordinal() - 1
1660    }
1661
1662    /// Returns the day of week.
1663    ///
1664    /// # Example
1665    ///
1666    /// ```
1667    /// use chrono::{NaiveDate, Datelike, Weekday};
1668    ///
1669    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().weekday(), Weekday::Tue);
1670    /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().weekday(), Weekday::Fri);
1671    /// ```
1672    #[inline]
1673    fn weekday(&self) -> Weekday {
1674        self.weekday()
1675    }
1676
1677    #[inline]
1678    fn iso_week(&self) -> IsoWeek {
1679        isoweek::iso_week_from_yof(self.year(), self.of())
1680    }
1681
1682    /// Makes a new `NaiveDate` with the year number changed, while keeping the same month and day.
1683    ///
1684    /// # Errors
1685    ///
1686    /// Returns `None` if the resulting date does not exist, or when the `NaiveDate` would be
1687    /// out of range.
1688    ///
1689    /// # Example
1690    ///
1691    /// ```
1692    /// use chrono::{NaiveDate, Datelike};
1693    ///
1694    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_year(2016),
1695    ///            Some(NaiveDate::from_ymd_opt(2016, 9, 8).unwrap()));
1696    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_year(-308),
1697    ///            Some(NaiveDate::from_ymd_opt(-308, 9, 8).unwrap()));
1698    /// ```
1699    ///
1700    /// A leap day (February 29) is a good example that this method can return `None`.
1701    ///
1702    /// ```
1703    /// # use chrono::{NaiveDate, Datelike};
1704    /// assert!(NaiveDate::from_ymd_opt(2016, 2, 29).unwrap().with_year(2015).is_none());
1705    /// assert!(NaiveDate::from_ymd_opt(2016, 2, 29).unwrap().with_year(2020).is_some());
1706    /// ```
1707    #[inline]
1708    fn with_year(&self, year: i32) -> Option<NaiveDate> {
1709        // we need to operate with `mdf` since we should keep the month and day number as is
1710        let mdf = self.mdf();
1711
1712        // adjust the flags as needed
1713        let flags = YearFlags::from_year(year);
1714        let mdf = mdf.with_flags(flags);
1715
1716        NaiveDate::from_mdf(year, mdf)
1717    }
1718
1719    /// Makes a new `NaiveDate` with the month number (starting from 1) changed.
1720    ///
1721    /// # Errors
1722    ///
1723    /// Returns `None` if the resulting date does not exist, or if the value for `month` is invalid.
1724    ///
1725    /// # Example
1726    ///
1727    /// ```
1728    /// use chrono::{NaiveDate, Datelike};
1729    ///
1730    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_month(10),
1731    ///            Some(NaiveDate::from_ymd_opt(2015, 10, 8).unwrap()));
1732    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_month(13), None); // no month 13
1733    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 30).unwrap().with_month(2), None); // no February 30
1734    /// ```
1735    #[inline]
1736    fn with_month(&self, month: u32) -> Option<NaiveDate> {
1737        self.with_mdf(self.mdf().with_month(month)?)
1738    }
1739
1740    /// Makes a new `NaiveDate` with the month number (starting from 0) changed.
1741    ///
1742    /// # Errors
1743    ///
1744    /// Returns `None` if the resulting date does not exist, or if the value for `month0` is
1745    /// invalid.
1746    ///
1747    /// # Example
1748    ///
1749    /// ```
1750    /// use chrono::{NaiveDate, Datelike};
1751    ///
1752    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_month0(9),
1753    ///            Some(NaiveDate::from_ymd_opt(2015, 10, 8).unwrap()));
1754    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_month0(12), None); // no month 13
1755    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 30).unwrap().with_month0(1), None); // no February 30
1756    /// ```
1757    #[inline]
1758    fn with_month0(&self, month0: u32) -> Option<NaiveDate> {
1759        let month = month0.checked_add(1)?;
1760        self.with_mdf(self.mdf().with_month(month)?)
1761    }
1762
1763    /// Makes a new `NaiveDate` with the day of month (starting from 1) changed.
1764    ///
1765    /// # Errors
1766    ///
1767    /// Returns `None` if the resulting date does not exist, or if the value for `day` is invalid.
1768    ///
1769    /// # Example
1770    ///
1771    /// ```
1772    /// use chrono::{NaiveDate, Datelike};
1773    ///
1774    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_day(30),
1775    ///            Some(NaiveDate::from_ymd_opt(2015, 9, 30).unwrap()));
1776    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_day(31),
1777    ///            None); // no September 31
1778    /// ```
1779    #[inline]
1780    fn with_day(&self, day: u32) -> Option<NaiveDate> {
1781        self.with_mdf(self.mdf().with_day(day)?)
1782    }
1783
1784    /// Makes a new `NaiveDate` with the day of month (starting from 0) changed.
1785    ///
1786    /// # Errors
1787    ///
1788    /// Returns `None` if the resulting date does not exist, or if the value for `day0` is invalid.
1789    ///
1790    /// # Example
1791    ///
1792    /// ```
1793    /// use chrono::{NaiveDate, Datelike};
1794    ///
1795    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_day0(29),
1796    ///            Some(NaiveDate::from_ymd_opt(2015, 9, 30).unwrap()));
1797    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_day0(30),
1798    ///            None); // no September 31
1799    /// ```
1800    #[inline]
1801    fn with_day0(&self, day0: u32) -> Option<NaiveDate> {
1802        let day = day0.checked_add(1)?;
1803        self.with_mdf(self.mdf().with_day(day)?)
1804    }
1805
1806    /// Makes a new `NaiveDate` with the day of year (starting from 1) changed.
1807    ///
1808    /// # Errors
1809    ///
1810    /// Returns `None` if the resulting date does not exist, or if the value for `ordinal` is
1811    /// invalid.
1812    ///
1813    /// # Example
1814    ///
1815    /// ```
1816    /// use chrono::{NaiveDate, Datelike};
1817    ///
1818    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 1, 1).unwrap().with_ordinal(60),
1819    ///            Some(NaiveDate::from_ymd_opt(2015, 3, 1).unwrap()));
1820    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 1, 1).unwrap().with_ordinal(366),
1821    ///            None); // 2015 had only 365 days
1822    ///
1823    /// assert_eq!(NaiveDate::from_ymd_opt(2016, 1, 1).unwrap().with_ordinal(60),
1824    ///            Some(NaiveDate::from_ymd_opt(2016, 2, 29).unwrap()));
1825    /// assert_eq!(NaiveDate::from_ymd_opt(2016, 1, 1).unwrap().with_ordinal(366),
1826    ///            Some(NaiveDate::from_ymd_opt(2016, 12, 31).unwrap()));
1827    /// ```
1828    #[inline]
1829    fn with_ordinal(&self, ordinal: u32) -> Option<NaiveDate> {
1830        self.of().with_ordinal(ordinal).map(|of| self.with_of(of))
1831    }
1832
1833    /// Makes a new `NaiveDate` with the day of year (starting from 0) changed.
1834    ///
1835    /// # Errors
1836    ///
1837    /// Returns `None` if the resulting date does not exist, or if the value for `ordinal0` is
1838    /// invalid.
1839    ///
1840    /// # Example
1841    ///
1842    /// ```
1843    /// use chrono::{NaiveDate, Datelike};
1844    ///
1845    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 1, 1).unwrap().with_ordinal0(59),
1846    ///            Some(NaiveDate::from_ymd_opt(2015, 3, 1).unwrap()));
1847    /// assert_eq!(NaiveDate::from_ymd_opt(2015, 1, 1).unwrap().with_ordinal0(365),
1848    ///            None); // 2015 had only 365 days
1849    ///
1850    /// assert_eq!(NaiveDate::from_ymd_opt(2016, 1, 1).unwrap().with_ordinal0(59),
1851    ///            Some(NaiveDate::from_ymd_opt(2016, 2, 29).unwrap()));
1852    /// assert_eq!(NaiveDate::from_ymd_opt(2016, 1, 1).unwrap().with_ordinal0(365),
1853    ///            Some(NaiveDate::from_ymd_opt(2016, 12, 31).unwrap()));
1854    /// ```
1855    #[inline]
1856    fn with_ordinal0(&self, ordinal0: u32) -> Option<NaiveDate> {
1857        let ordinal = ordinal0.checked_add(1)?;
1858        self.with_ordinal(ordinal)
1859    }
1860}
1861
1862/// Add `TimeDelta` to `NaiveDate`.
1863///
1864/// This discards the fractional days in `TimeDelta`, rounding to the closest integral number of
1865/// days towards `TimeDelta::zero()`.
1866///
1867/// # Panics
1868///
1869/// Panics if the resulting date would be out of range.
1870/// Consider using [`NaiveDate::checked_add_signed`] to get an `Option` instead.
1871///
1872/// # Example
1873///
1874/// ```
1875/// use chrono::{TimeDelta, NaiveDate};
1876///
1877/// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
1878///
1879/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::zero(),             from_ymd(2014, 1, 1));
1880/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::seconds(86399),     from_ymd(2014, 1, 1));
1881/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::seconds(-86399),    from_ymd(2014, 1, 1));
1882/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(1),            from_ymd(2014, 1, 2));
1883/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(-1),           from_ymd(2013, 12, 31));
1884/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(364),          from_ymd(2014, 12, 31));
1885/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(365*4 + 1),    from_ymd(2018, 1, 1));
1886/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(365*400 + 97), from_ymd(2414, 1, 1));
1887/// ```
1888///
1889/// [`NaiveDate::checked_add_signed`]: crate::NaiveDate::checked_add_signed
1890impl Add<TimeDelta> for NaiveDate {
1891    type Output = NaiveDate;
1892
1893    #[inline]
1894    fn add(self, rhs: TimeDelta) -> NaiveDate {
1895        self.checked_add_signed(rhs).expect("`NaiveDate + TimeDelta` overflowed")
1896    }
1897}
1898
1899/// Add-assign of `TimeDelta` to `NaiveDate`.
1900///
1901/// This discards the fractional days in `TimeDelta`, rounding to the closest integral number of days
1902/// towards `TimeDelta::zero()`.
1903///
1904/// # Panics
1905///
1906/// Panics if the resulting date would be out of range.
1907/// Consider using [`NaiveDate::checked_add_signed`] to get an `Option` instead.
1908impl AddAssign<TimeDelta> for NaiveDate {
1909    #[inline]
1910    fn add_assign(&mut self, rhs: TimeDelta) {
1911        *self = self.add(rhs);
1912    }
1913}
1914
1915/// Add `Months` to `NaiveDate`.
1916///
1917/// The result will be clamped to valid days in the resulting month, see `checked_add_months` for
1918/// details.
1919///
1920/// # Panics
1921///
1922/// Panics if the resulting date would be out of range.
1923/// Consider using `NaiveDate::checked_add_months` to get an `Option` instead.
1924///
1925/// # Example
1926///
1927/// ```
1928/// use chrono::{NaiveDate, Months};
1929///
1930/// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
1931///
1932/// assert_eq!(from_ymd(2014, 1, 1) + Months::new(1), from_ymd(2014, 2, 1));
1933/// assert_eq!(from_ymd(2014, 1, 1) + Months::new(11), from_ymd(2014, 12, 1));
1934/// assert_eq!(from_ymd(2014, 1, 1) + Months::new(12), from_ymd(2015, 1, 1));
1935/// assert_eq!(from_ymd(2014, 1, 1) + Months::new(13), from_ymd(2015, 2, 1));
1936/// assert_eq!(from_ymd(2014, 1, 31) + Months::new(1), from_ymd(2014, 2, 28));
1937/// assert_eq!(from_ymd(2020, 1, 31) + Months::new(1), from_ymd(2020, 2, 29));
1938/// ```
1939impl Add<Months> for NaiveDate {
1940    type Output = NaiveDate;
1941
1942    fn add(self, months: Months) -> Self::Output {
1943        self.checked_add_months(months).expect("`NaiveDate + Months` out of range")
1944    }
1945}
1946
1947/// Subtract `Months` from `NaiveDate`.
1948///
1949/// The result will be clamped to valid days in the resulting month, see `checked_sub_months` for
1950/// details.
1951///
1952/// # Panics
1953///
1954/// Panics if the resulting date would be out of range.
1955/// Consider using `NaiveDate::checked_sub_months` to get an `Option` instead.
1956///
1957/// # Example
1958///
1959/// ```
1960/// use chrono::{NaiveDate, Months};
1961///
1962/// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
1963///
1964/// assert_eq!(from_ymd(2014, 1, 1) - Months::new(11), from_ymd(2013, 2, 1));
1965/// assert_eq!(from_ymd(2014, 1, 1) - Months::new(12), from_ymd(2013, 1, 1));
1966/// assert_eq!(from_ymd(2014, 1, 1) - Months::new(13), from_ymd(2012, 12, 1));
1967/// ```
1968impl Sub<Months> for NaiveDate {
1969    type Output = NaiveDate;
1970
1971    fn sub(self, months: Months) -> Self::Output {
1972        self.checked_sub_months(months).expect("`NaiveDate - Months` out of range")
1973    }
1974}
1975
1976/// Add `Days` to `NaiveDate`.
1977///
1978/// # Panics
1979///
1980/// Panics if the resulting date would be out of range.
1981/// Consider using `NaiveDate::checked_add_days` to get an `Option` instead.
1982impl Add<Days> for NaiveDate {
1983    type Output = NaiveDate;
1984
1985    fn add(self, days: Days) -> Self::Output {
1986        self.checked_add_days(days).expect("`NaiveDate + Days` out of range")
1987    }
1988}
1989
1990/// Subtract `Days` from `NaiveDate`.
1991///
1992/// # Panics
1993///
1994/// Panics if the resulting date would be out of range.
1995/// Consider using `NaiveDate::checked_sub_days` to get an `Option` instead.
1996impl Sub<Days> for NaiveDate {
1997    type Output = NaiveDate;
1998
1999    fn sub(self, days: Days) -> Self::Output {
2000        self.checked_sub_days(days).expect("`NaiveDate - Days` out of range")
2001    }
2002}
2003
2004/// Subtract `TimeDelta` from `NaiveDate`.
2005///
2006/// This discards the fractional days in `TimeDelta`, rounding to the closest integral number of
2007/// days towards `TimeDelta::zero()`.
2008/// It is the same as the addition with a negated `TimeDelta`.
2009///
2010/// # Panics
2011///
2012/// Panics if the resulting date would be out of range.
2013/// Consider using [`NaiveDate::checked_sub_signed`] to get an `Option` instead.
2014///
2015/// # Example
2016///
2017/// ```
2018/// use chrono::{TimeDelta, NaiveDate};
2019///
2020/// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
2021///
2022/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::zero(),             from_ymd(2014, 1, 1));
2023/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::seconds(86399),     from_ymd(2014, 1, 1));
2024/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::seconds(-86399),    from_ymd(2014, 1, 1));
2025/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(1),            from_ymd(2013, 12, 31));
2026/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(-1),           from_ymd(2014, 1, 2));
2027/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(364),          from_ymd(2013, 1, 2));
2028/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(365*4 + 1),    from_ymd(2010, 1, 1));
2029/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(365*400 + 97), from_ymd(1614, 1, 1));
2030/// ```
2031///
2032/// [`NaiveDate::checked_sub_signed`]: crate::NaiveDate::checked_sub_signed
2033impl Sub<TimeDelta> for NaiveDate {
2034    type Output = NaiveDate;
2035
2036    #[inline]
2037    fn sub(self, rhs: TimeDelta) -> NaiveDate {
2038        self.checked_sub_signed(rhs).expect("`NaiveDate - TimeDelta` overflowed")
2039    }
2040}
2041
2042/// Subtract-assign `TimeDelta` from `NaiveDate`.
2043///
2044/// This discards the fractional days in `TimeDelta`, rounding to the closest integral number of
2045/// days towards `TimeDelta::zero()`.
2046/// It is the same as the addition with a negated `TimeDelta`.
2047///
2048/// # Panics
2049///
2050/// Panics if the resulting date would be out of range.
2051/// Consider using [`NaiveDate::checked_sub_signed`] to get an `Option` instead.
2052impl SubAssign<TimeDelta> for NaiveDate {
2053    #[inline]
2054    fn sub_assign(&mut self, rhs: TimeDelta) {
2055        *self = self.sub(rhs);
2056    }
2057}
2058
2059/// Subtracts another `NaiveDate` from the current date.
2060/// Returns a `TimeDelta` of integral numbers.
2061///
2062/// This does not overflow or underflow at all,
2063/// as all possible output fits in the range of `TimeDelta`.
2064///
2065/// The implementation is a wrapper around
2066/// [`NaiveDate::signed_duration_since`](#method.signed_duration_since).
2067///
2068/// # Example
2069///
2070/// ```
2071/// use chrono::{TimeDelta, NaiveDate};
2072///
2073/// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
2074///
2075/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2014, 1, 1), TimeDelta::zero());
2076/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 12, 31), TimeDelta::days(1));
2077/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2014, 1, 2), TimeDelta::days(-1));
2078/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 9, 23), TimeDelta::days(100));
2079/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 1, 1), TimeDelta::days(365));
2080/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2010, 1, 1), TimeDelta::days(365*4 + 1));
2081/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(1614, 1, 1), TimeDelta::days(365*400 + 97));
2082/// ```
2083impl Sub<NaiveDate> for NaiveDate {
2084    type Output = TimeDelta;
2085
2086    #[inline]
2087    fn sub(self, rhs: NaiveDate) -> TimeDelta {
2088        self.signed_duration_since(rhs)
2089    }
2090}
2091
2092impl From<NaiveDateTime> for NaiveDate {
2093    fn from(naive_datetime: NaiveDateTime) -> Self {
2094        naive_datetime.date()
2095    }
2096}
2097
2098/// Iterator over `NaiveDate` with a step size of one day.
2099#[derive(Debug, Copy, Clone, Hash, PartialEq, PartialOrd, Eq, Ord)]
2100pub struct NaiveDateDaysIterator {
2101    value: NaiveDate,
2102}
2103
2104impl Iterator for NaiveDateDaysIterator {
2105    type Item = NaiveDate;
2106
2107    fn next(&mut self) -> Option<Self::Item> {
2108        // We return the current value, and have no way to return `NaiveDate::MAX`.
2109        let current = self.value;
2110        // This can't panic because current is < NaiveDate::MAX:
2111        self.value = current.succ_opt()?;
2112        Some(current)
2113    }
2114
2115    fn size_hint(&self) -> (usize, Option<usize>) {
2116        let exact_size = NaiveDate::MAX.signed_duration_since(self.value).num_days();
2117        (exact_size as usize, Some(exact_size as usize))
2118    }
2119}
2120
2121impl ExactSizeIterator for NaiveDateDaysIterator {}
2122
2123impl DoubleEndedIterator for NaiveDateDaysIterator {
2124    fn next_back(&mut self) -> Option<Self::Item> {
2125        // We return the current value, and have no way to return `NaiveDate::MIN`.
2126        let current = self.value;
2127        self.value = current.pred_opt()?;
2128        Some(current)
2129    }
2130}
2131
2132impl FusedIterator for NaiveDateDaysIterator {}
2133
2134/// Iterator over `NaiveDate` with a step size of one week.
2135#[derive(Debug, Copy, Clone, Hash, PartialEq, PartialOrd, Eq, Ord)]
2136pub struct NaiveDateWeeksIterator {
2137    value: NaiveDate,
2138}
2139
2140impl Iterator for NaiveDateWeeksIterator {
2141    type Item = NaiveDate;
2142
2143    fn next(&mut self) -> Option<Self::Item> {
2144        let current = self.value;
2145        self.value = current.checked_add_signed(TimeDelta::weeks(1))?;
2146        Some(current)
2147    }
2148
2149    fn size_hint(&self) -> (usize, Option<usize>) {
2150        let exact_size = NaiveDate::MAX.signed_duration_since(self.value).num_weeks();
2151        (exact_size as usize, Some(exact_size as usize))
2152    }
2153}
2154
2155impl ExactSizeIterator for NaiveDateWeeksIterator {}
2156
2157impl DoubleEndedIterator for NaiveDateWeeksIterator {
2158    fn next_back(&mut self) -> Option<Self::Item> {
2159        let current = self.value;
2160        self.value = current.checked_sub_signed(TimeDelta::weeks(1))?;
2161        Some(current)
2162    }
2163}
2164
2165impl FusedIterator for NaiveDateWeeksIterator {}
2166
2167/// The `Debug` output of the naive date `d` is the same as
2168/// [`d.format("%Y-%m-%d")`](crate::format::strftime).
2169///
2170/// The string printed can be readily parsed via the `parse` method on `str`.
2171///
2172/// # Example
2173///
2174/// ```
2175/// use chrono::NaiveDate;
2176///
2177/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(2015,  9,  5).unwrap()), "2015-09-05");
2178/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(   0,  1,  1).unwrap()), "0000-01-01");
2179/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(9999, 12, 31).unwrap()), "9999-12-31");
2180/// ```
2181///
2182/// ISO 8601 requires an explicit sign for years before 1 BCE or after 9999 CE.
2183///
2184/// ```
2185/// # use chrono::NaiveDate;
2186/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(   -1,  1,  1).unwrap()),  "-0001-01-01");
2187/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(10000, 12, 31).unwrap()), "+10000-12-31");
2188/// ```
2189impl fmt::Debug for NaiveDate {
2190    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2191        use core::fmt::Write;
2192
2193        let year = self.year();
2194        let mdf = self.mdf();
2195        if (0..=9999).contains(&year) {
2196            write_hundreds(f, (year / 100) as u8)?;
2197            write_hundreds(f, (year % 100) as u8)?;
2198        } else {
2199            // ISO 8601 requires the explicit sign for out-of-range years
2200            write!(f, "{:+05}", year)?;
2201        }
2202
2203        f.write_char('-')?;
2204        write_hundreds(f, mdf.month() as u8)?;
2205        f.write_char('-')?;
2206        write_hundreds(f, mdf.day() as u8)
2207    }
2208}
2209
2210/// The `Display` output of the naive date `d` is the same as
2211/// [`d.format("%Y-%m-%d")`](crate::format::strftime).
2212///
2213/// The string printed can be readily parsed via the `parse` method on `str`.
2214///
2215/// # Example
2216///
2217/// ```
2218/// use chrono::NaiveDate;
2219///
2220/// assert_eq!(format!("{}", NaiveDate::from_ymd_opt(2015,  9,  5).unwrap()), "2015-09-05");
2221/// assert_eq!(format!("{}", NaiveDate::from_ymd_opt(   0,  1,  1).unwrap()), "0000-01-01");
2222/// assert_eq!(format!("{}", NaiveDate::from_ymd_opt(9999, 12, 31).unwrap()), "9999-12-31");
2223/// ```
2224///
2225/// ISO 8601 requires an explicit sign for years before 1 BCE or after 9999 CE.
2226///
2227/// ```
2228/// # use chrono::NaiveDate;
2229/// assert_eq!(format!("{}", NaiveDate::from_ymd_opt(   -1,  1,  1).unwrap()),  "-0001-01-01");
2230/// assert_eq!(format!("{}", NaiveDate::from_ymd_opt(10000, 12, 31).unwrap()), "+10000-12-31");
2231/// ```
2232impl fmt::Display for NaiveDate {
2233    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2234        fmt::Debug::fmt(self, f)
2235    }
2236}
2237
2238/// Parsing a `str` into a `NaiveDate` uses the same format,
2239/// [`%Y-%m-%d`](crate::format::strftime), as in `Debug` and `Display`.
2240///
2241/// # Example
2242///
2243/// ```
2244/// use chrono::NaiveDate;
2245///
2246/// let d = NaiveDate::from_ymd_opt(2015, 9, 18).unwrap();
2247/// assert_eq!("2015-09-18".parse::<NaiveDate>(), Ok(d));
2248///
2249/// let d = NaiveDate::from_ymd_opt(12345, 6, 7).unwrap();
2250/// assert_eq!("+12345-6-7".parse::<NaiveDate>(), Ok(d));
2251///
2252/// assert!("foo".parse::<NaiveDate>().is_err());
2253/// ```
2254impl str::FromStr for NaiveDate {
2255    type Err = ParseError;
2256
2257    fn from_str(s: &str) -> ParseResult<NaiveDate> {
2258        const ITEMS: &[Item<'static>] = &[
2259            Item::Numeric(Numeric::Year, Pad::Zero),
2260            Item::Space(""),
2261            Item::Literal("-"),
2262            Item::Numeric(Numeric::Month, Pad::Zero),
2263            Item::Space(""),
2264            Item::Literal("-"),
2265            Item::Numeric(Numeric::Day, Pad::Zero),
2266            Item::Space(""),
2267        ];
2268
2269        let mut parsed = Parsed::new();
2270        parse(&mut parsed, s, ITEMS.iter())?;
2271        parsed.to_naive_date()
2272    }
2273}
2274
2275/// The default value for a NaiveDate is 1st of January 1970.
2276///
2277/// # Example
2278///
2279/// ```rust
2280/// use chrono::NaiveDate;
2281///
2282/// let default_date = NaiveDate::default();
2283/// assert_eq!(default_date, NaiveDate::from_ymd_opt(1970, 1, 1).unwrap());
2284/// ```
2285impl Default for NaiveDate {
2286    fn default() -> Self {
2287        NaiveDate::from_ymd_opt(1970, 1, 1).unwrap()
2288    }
2289}
2290
2291const fn div_mod_floor(val: i32, div: i32) -> (i32, i32) {
2292    (val.div_euclid(div), val.rem_euclid(div))
2293}
2294
2295#[cfg(all(test, any(feature = "rustc-serialize", feature = "serde")))]
2296fn test_encodable_json<F, E>(to_string: F)
2297where
2298    F: Fn(&NaiveDate) -> Result<String, E>,
2299    E: ::std::fmt::Debug,
2300{
2301    assert_eq!(
2302        to_string(&NaiveDate::from_ymd_opt(2014, 7, 24).unwrap()).ok(),
2303        Some(r#""2014-07-24""#.into())
2304    );
2305    assert_eq!(
2306        to_string(&NaiveDate::from_ymd_opt(0, 1, 1).unwrap()).ok(),
2307        Some(r#""0000-01-01""#.into())
2308    );
2309    assert_eq!(
2310        to_string(&NaiveDate::from_ymd_opt(-1, 12, 31).unwrap()).ok(),
2311        Some(r#""-0001-12-31""#.into())
2312    );
2313    assert_eq!(to_string(&NaiveDate::MIN).ok(), Some(r#""-262143-01-01""#.into()));
2314    assert_eq!(to_string(&NaiveDate::MAX).ok(), Some(r#""+262142-12-31""#.into()));
2315}
2316
2317#[cfg(all(test, any(feature = "rustc-serialize", feature = "serde")))]
2318fn test_decodable_json<F, E>(from_str: F)
2319where
2320    F: Fn(&str) -> Result<NaiveDate, E>,
2321    E: ::std::fmt::Debug,
2322{
2323    use std::{i32, i64};
2324
2325    assert_eq!(
2326        from_str(r#""2016-07-08""#).ok(),
2327        Some(NaiveDate::from_ymd_opt(2016, 7, 8).unwrap())
2328    );
2329    assert_eq!(from_str(r#""2016-7-8""#).ok(), Some(NaiveDate::from_ymd_opt(2016, 7, 8).unwrap()));
2330    assert_eq!(from_str(r#""+002016-07-08""#).ok(), NaiveDate::from_ymd_opt(2016, 7, 8));
2331    assert_eq!(from_str(r#""0000-01-01""#).ok(), Some(NaiveDate::from_ymd_opt(0, 1, 1).unwrap()));
2332    assert_eq!(from_str(r#""0-1-1""#).ok(), Some(NaiveDate::from_ymd_opt(0, 1, 1).unwrap()));
2333    assert_eq!(
2334        from_str(r#""-0001-12-31""#).ok(),
2335        Some(NaiveDate::from_ymd_opt(-1, 12, 31).unwrap())
2336    );
2337    assert_eq!(from_str(r#""-262143-01-01""#).ok(), Some(NaiveDate::MIN));
2338    assert_eq!(from_str(r#""+262142-12-31""#).ok(), Some(NaiveDate::MAX));
2339
2340    // bad formats
2341    assert!(from_str(r#""""#).is_err());
2342    assert!(from_str(r#""20001231""#).is_err());
2343    assert!(from_str(r#""2000-00-00""#).is_err());
2344    assert!(from_str(r#""2000-02-30""#).is_err());
2345    assert!(from_str(r#""2001-02-29""#).is_err());
2346    assert!(from_str(r#""2002-002-28""#).is_err());
2347    assert!(from_str(r#""yyyy-mm-dd""#).is_err());
2348    assert!(from_str(r#"0"#).is_err());
2349    assert!(from_str(r#"20.01"#).is_err());
2350    assert!(from_str(&i32::MIN.to_string()).is_err());
2351    assert!(from_str(&i32::MAX.to_string()).is_err());
2352    assert!(from_str(&i64::MIN.to_string()).is_err());
2353    assert!(from_str(&i64::MAX.to_string()).is_err());
2354    assert!(from_str(r#"{}"#).is_err());
2355    // pre-0.3.0 rustc-serialize format is now invalid
2356    assert!(from_str(r#"{"ymdf":20}"#).is_err());
2357    assert!(from_str(r#"null"#).is_err());
2358}
2359
2360#[cfg(feature = "rustc-serialize")]
2361mod rustc_serialize {
2362    use super::NaiveDate;
2363    use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
2364
2365    impl Encodable for NaiveDate {
2366        fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
2367            format!("{:?}", self).encode(s)
2368        }
2369    }
2370
2371    impl Decodable for NaiveDate {
2372        fn decode<D: Decoder>(d: &mut D) -> Result<NaiveDate, D::Error> {
2373            d.read_str()?.parse().map_err(|_| d.error("invalid date"))
2374        }
2375    }
2376
2377    #[cfg(test)]
2378    mod tests {
2379        use crate::naive::date::{test_decodable_json, test_encodable_json};
2380        use rustc_serialize::json;
2381
2382        #[test]
2383        fn test_encodable() {
2384            test_encodable_json(json::encode);
2385        }
2386
2387        #[test]
2388        fn test_decodable() {
2389            test_decodable_json(json::decode);
2390        }
2391    }
2392}
2393
2394#[cfg(feature = "serde")]
2395mod serde {
2396    use super::NaiveDate;
2397    use core::fmt;
2398    use serde::{de, ser};
2399
2400    // TODO not very optimized for space (binary formats would want something better)
2401
2402    impl ser::Serialize for NaiveDate {
2403        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2404        where
2405            S: ser::Serializer,
2406        {
2407            struct FormatWrapped<'a, D: 'a> {
2408                inner: &'a D,
2409            }
2410
2411            impl<'a, D: fmt::Debug> fmt::Display for FormatWrapped<'a, D> {
2412                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2413                    self.inner.fmt(f)
2414                }
2415            }
2416
2417            serializer.collect_str(&FormatWrapped { inner: &self })
2418        }
2419    }
2420
2421    struct NaiveDateVisitor;
2422
2423    impl<'de> de::Visitor<'de> for NaiveDateVisitor {
2424        type Value = NaiveDate;
2425
2426        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
2427            formatter.write_str("a formatted date string")
2428        }
2429
2430        fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
2431        where
2432            E: de::Error,
2433        {
2434            value.parse().map_err(E::custom)
2435        }
2436    }
2437
2438    impl<'de> de::Deserialize<'de> for NaiveDate {
2439        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2440        where
2441            D: de::Deserializer<'de>,
2442        {
2443            deserializer.deserialize_str(NaiveDateVisitor)
2444        }
2445    }
2446
2447    #[cfg(test)]
2448    mod tests {
2449        use crate::naive::date::{test_decodable_json, test_encodable_json};
2450        use crate::NaiveDate;
2451
2452        #[test]
2453        fn test_serde_serialize() {
2454            test_encodable_json(serde_json::to_string);
2455        }
2456
2457        #[test]
2458        fn test_serde_deserialize() {
2459            test_decodable_json(|input| serde_json::from_str(input));
2460        }
2461
2462        #[test]
2463        fn test_serde_bincode() {
2464            // Bincode is relevant to test separately from JSON because
2465            // it is not self-describing.
2466            use bincode::{deserialize, serialize};
2467
2468            let d = NaiveDate::from_ymd_opt(2014, 7, 24).unwrap();
2469            let encoded = serialize(&d).unwrap();
2470            let decoded: NaiveDate = deserialize(&encoded).unwrap();
2471            assert_eq!(d, decoded);
2472        }
2473    }
2474}
2475
2476#[cfg(test)]
2477mod tests {
2478    use super::{Days, Months, NaiveDate, MAX_YEAR, MIN_YEAR};
2479    use crate::naive::internals::YearFlags;
2480    use crate::{Datelike, TimeDelta, Weekday};
2481
2482    // as it is hard to verify year flags in `NaiveDate::MIN` and `NaiveDate::MAX`,
2483    // we use a separate run-time test.
2484    #[test]
2485    fn test_date_bounds() {
2486        let calculated_min = NaiveDate::from_ymd_opt(MIN_YEAR, 1, 1).unwrap();
2487        let calculated_max = NaiveDate::from_ymd_opt(MAX_YEAR, 12, 31).unwrap();
2488        assert!(
2489            NaiveDate::MIN == calculated_min,
2490            "`NaiveDate::MIN` should have year flag {:?}",
2491            calculated_min.of().flags()
2492        );
2493        assert!(
2494            NaiveDate::MAX == calculated_max,
2495            "`NaiveDate::MAX` should have year flag {:?} and ordinal {}",
2496            calculated_max.of().flags(),
2497            calculated_max.of().ordinal()
2498        );
2499
2500        // let's also check that the entire range do not exceed 2^44 seconds
2501        // (sometimes used for bounding `TimeDelta` against overflow)
2502        let maxsecs = NaiveDate::MAX.signed_duration_since(NaiveDate::MIN).num_seconds();
2503        let maxsecs = maxsecs + 86401; // also take care of DateTime
2504        assert!(
2505            maxsecs < (1 << MAX_BITS),
2506            "The entire `NaiveDate` range somehow exceeds 2^{} seconds",
2507            MAX_BITS
2508        );
2509
2510        const BEFORE_MIN: NaiveDate = NaiveDate::BEFORE_MIN;
2511        assert_eq!(BEFORE_MIN.of().flags(), YearFlags::from_year(BEFORE_MIN.year()));
2512        assert_eq!((BEFORE_MIN.month(), BEFORE_MIN.day()), (12, 31));
2513
2514        const AFTER_MAX: NaiveDate = NaiveDate::AFTER_MAX;
2515        assert_eq!(AFTER_MAX.of().flags(), YearFlags::from_year(AFTER_MAX.year()));
2516        assert_eq!((AFTER_MAX.month(), AFTER_MAX.day()), (1, 1));
2517    }
2518
2519    #[test]
2520    fn diff_months() {
2521        // identity
2522        assert_eq!(
2523            NaiveDate::from_ymd_opt(2022, 8, 3).unwrap().checked_add_months(Months::new(0)),
2524            Some(NaiveDate::from_ymd_opt(2022, 8, 3).unwrap())
2525        );
2526
2527        // add with months exceeding `i32::MAX`
2528        assert_eq!(
2529            NaiveDate::from_ymd_opt(2022, 8, 3)
2530                .unwrap()
2531                .checked_add_months(Months::new(i32::MAX as u32 + 1)),
2532            None
2533        );
2534
2535        // sub with months exceeding `i32::MIN`
2536        assert_eq!(
2537            NaiveDate::from_ymd_opt(2022, 8, 3)
2538                .unwrap()
2539                .checked_sub_months(Months::new(i32::MIN.unsigned_abs() + 1)),
2540            None
2541        );
2542
2543        // add overflowing year
2544        assert_eq!(NaiveDate::MAX.checked_add_months(Months::new(1)), None);
2545
2546        // add underflowing year
2547        assert_eq!(NaiveDate::MIN.checked_sub_months(Months::new(1)), None);
2548
2549        // sub crossing year 0 boundary
2550        assert_eq!(
2551            NaiveDate::from_ymd_opt(2022, 8, 3).unwrap().checked_sub_months(Months::new(2050 * 12)),
2552            Some(NaiveDate::from_ymd_opt(-28, 8, 3).unwrap())
2553        );
2554
2555        // add crossing year boundary
2556        assert_eq!(
2557            NaiveDate::from_ymd_opt(2022, 8, 3).unwrap().checked_add_months(Months::new(6)),
2558            Some(NaiveDate::from_ymd_opt(2023, 2, 3).unwrap())
2559        );
2560
2561        // sub crossing year boundary
2562        assert_eq!(
2563            NaiveDate::from_ymd_opt(2022, 8, 3).unwrap().checked_sub_months(Months::new(10)),
2564            Some(NaiveDate::from_ymd_opt(2021, 10, 3).unwrap())
2565        );
2566
2567        // add clamping day, non-leap year
2568        assert_eq!(
2569            NaiveDate::from_ymd_opt(2022, 1, 29).unwrap().checked_add_months(Months::new(1)),
2570            Some(NaiveDate::from_ymd_opt(2022, 2, 28).unwrap())
2571        );
2572
2573        // add to leap day
2574        assert_eq!(
2575            NaiveDate::from_ymd_opt(2022, 10, 29).unwrap().checked_add_months(Months::new(16)),
2576            Some(NaiveDate::from_ymd_opt(2024, 2, 29).unwrap())
2577        );
2578
2579        // add into december
2580        assert_eq!(
2581            NaiveDate::from_ymd_opt(2022, 10, 31).unwrap().checked_add_months(Months::new(2)),
2582            Some(NaiveDate::from_ymd_opt(2022, 12, 31).unwrap())
2583        );
2584
2585        // sub into december
2586        assert_eq!(
2587            NaiveDate::from_ymd_opt(2022, 10, 31).unwrap().checked_sub_months(Months::new(10)),
2588            Some(NaiveDate::from_ymd_opt(2021, 12, 31).unwrap())
2589        );
2590
2591        // add into january
2592        assert_eq!(
2593            NaiveDate::from_ymd_opt(2022, 8, 3).unwrap().checked_add_months(Months::new(5)),
2594            Some(NaiveDate::from_ymd_opt(2023, 1, 3).unwrap())
2595        );
2596
2597        // sub into january
2598        assert_eq!(
2599            NaiveDate::from_ymd_opt(2022, 8, 3).unwrap().checked_sub_months(Months::new(7)),
2600            Some(NaiveDate::from_ymd_opt(2022, 1, 3).unwrap())
2601        );
2602    }
2603
2604    #[test]
2605    fn test_readme_doomsday() {
2606        for y in NaiveDate::MIN.year()..=NaiveDate::MAX.year() {
2607            // even months
2608            let d4 = NaiveDate::from_ymd_opt(y, 4, 4).unwrap();
2609            let d6 = NaiveDate::from_ymd_opt(y, 6, 6).unwrap();
2610            let d8 = NaiveDate::from_ymd_opt(y, 8, 8).unwrap();
2611            let d10 = NaiveDate::from_ymd_opt(y, 10, 10).unwrap();
2612            let d12 = NaiveDate::from_ymd_opt(y, 12, 12).unwrap();
2613
2614            // nine to five, seven-eleven
2615            let d59 = NaiveDate::from_ymd_opt(y, 5, 9).unwrap();
2616            let d95 = NaiveDate::from_ymd_opt(y, 9, 5).unwrap();
2617            let d711 = NaiveDate::from_ymd_opt(y, 7, 11).unwrap();
2618            let d117 = NaiveDate::from_ymd_opt(y, 11, 7).unwrap();
2619
2620            // "March 0"
2621            let d30 = NaiveDate::from_ymd_opt(y, 3, 1).unwrap().pred_opt().unwrap();
2622
2623            let weekday = d30.weekday();
2624            let other_dates = [d4, d6, d8, d10, d12, d59, d95, d711, d117];
2625            assert!(other_dates.iter().all(|d| d.weekday() == weekday));
2626        }
2627    }
2628
2629    #[test]
2630    fn test_date_from_ymd() {
2631        let ymd_opt = NaiveDate::from_ymd_opt;
2632
2633        assert!(ymd_opt(2012, 0, 1).is_none());
2634        assert!(ymd_opt(2012, 1, 1).is_some());
2635        assert!(ymd_opt(2012, 2, 29).is_some());
2636        assert!(ymd_opt(2014, 2, 29).is_none());
2637        assert!(ymd_opt(2014, 3, 0).is_none());
2638        assert!(ymd_opt(2014, 3, 1).is_some());
2639        assert!(ymd_opt(2014, 3, 31).is_some());
2640        assert!(ymd_opt(2014, 3, 32).is_none());
2641        assert!(ymd_opt(2014, 12, 31).is_some());
2642        assert!(ymd_opt(2014, 13, 1).is_none());
2643    }
2644
2645    #[test]
2646    fn test_date_from_yo() {
2647        let yo_opt = NaiveDate::from_yo_opt;
2648        let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
2649
2650        assert_eq!(yo_opt(2012, 0), None);
2651        assert_eq!(yo_opt(2012, 1), Some(ymd(2012, 1, 1)));
2652        assert_eq!(yo_opt(2012, 2), Some(ymd(2012, 1, 2)));
2653        assert_eq!(yo_opt(2012, 32), Some(ymd(2012, 2, 1)));
2654        assert_eq!(yo_opt(2012, 60), Some(ymd(2012, 2, 29)));
2655        assert_eq!(yo_opt(2012, 61), Some(ymd(2012, 3, 1)));
2656        assert_eq!(yo_opt(2012, 100), Some(ymd(2012, 4, 9)));
2657        assert_eq!(yo_opt(2012, 200), Some(ymd(2012, 7, 18)));
2658        assert_eq!(yo_opt(2012, 300), Some(ymd(2012, 10, 26)));
2659        assert_eq!(yo_opt(2012, 366), Some(ymd(2012, 12, 31)));
2660        assert_eq!(yo_opt(2012, 367), None);
2661
2662        assert_eq!(yo_opt(2014, 0), None);
2663        assert_eq!(yo_opt(2014, 1), Some(ymd(2014, 1, 1)));
2664        assert_eq!(yo_opt(2014, 2), Some(ymd(2014, 1, 2)));
2665        assert_eq!(yo_opt(2014, 32), Some(ymd(2014, 2, 1)));
2666        assert_eq!(yo_opt(2014, 59), Some(ymd(2014, 2, 28)));
2667        assert_eq!(yo_opt(2014, 60), Some(ymd(2014, 3, 1)));
2668        assert_eq!(yo_opt(2014, 100), Some(ymd(2014, 4, 10)));
2669        assert_eq!(yo_opt(2014, 200), Some(ymd(2014, 7, 19)));
2670        assert_eq!(yo_opt(2014, 300), Some(ymd(2014, 10, 27)));
2671        assert_eq!(yo_opt(2014, 365), Some(ymd(2014, 12, 31)));
2672        assert_eq!(yo_opt(2014, 366), None);
2673    }
2674
2675    #[test]
2676    fn test_date_from_isoywd() {
2677        let isoywd_opt = NaiveDate::from_isoywd_opt;
2678        let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
2679
2680        assert_eq!(isoywd_opt(2004, 0, Weekday::Sun), None);
2681        assert_eq!(isoywd_opt(2004, 1, Weekday::Mon), Some(ymd(2003, 12, 29)));
2682        assert_eq!(isoywd_opt(2004, 1, Weekday::Sun), Some(ymd(2004, 1, 4)));
2683        assert_eq!(isoywd_opt(2004, 2, Weekday::Mon), Some(ymd(2004, 1, 5)));
2684        assert_eq!(isoywd_opt(2004, 2, Weekday::Sun), Some(ymd(2004, 1, 11)));
2685        assert_eq!(isoywd_opt(2004, 52, Weekday::Mon), Some(ymd(2004, 12, 20)));
2686        assert_eq!(isoywd_opt(2004, 52, Weekday::Sun), Some(ymd(2004, 12, 26)));
2687        assert_eq!(isoywd_opt(2004, 53, Weekday::Mon), Some(ymd(2004, 12, 27)));
2688        assert_eq!(isoywd_opt(2004, 53, Weekday::Sun), Some(ymd(2005, 1, 2)));
2689        assert_eq!(isoywd_opt(2004, 54, Weekday::Mon), None);
2690
2691        assert_eq!(isoywd_opt(2011, 0, Weekday::Sun), None);
2692        assert_eq!(isoywd_opt(2011, 1, Weekday::Mon), Some(ymd(2011, 1, 3)));
2693        assert_eq!(isoywd_opt(2011, 1, Weekday::Sun), Some(ymd(2011, 1, 9)));
2694        assert_eq!(isoywd_opt(2011, 2, Weekday::Mon), Some(ymd(2011, 1, 10)));
2695        assert_eq!(isoywd_opt(2011, 2, Weekday::Sun), Some(ymd(2011, 1, 16)));
2696
2697        assert_eq!(isoywd_opt(2018, 51, Weekday::Mon), Some(ymd(2018, 12, 17)));
2698        assert_eq!(isoywd_opt(2018, 51, Weekday::Sun), Some(ymd(2018, 12, 23)));
2699        assert_eq!(isoywd_opt(2018, 52, Weekday::Mon), Some(ymd(2018, 12, 24)));
2700        assert_eq!(isoywd_opt(2018, 52, Weekday::Sun), Some(ymd(2018, 12, 30)));
2701        assert_eq!(isoywd_opt(2018, 53, Weekday::Mon), None);
2702    }
2703
2704    #[test]
2705    fn test_date_from_isoywd_and_iso_week() {
2706        for year in 2000..2401 {
2707            for week in 1..54 {
2708                for &weekday in [
2709                    Weekday::Mon,
2710                    Weekday::Tue,
2711                    Weekday::Wed,
2712                    Weekday::Thu,
2713                    Weekday::Fri,
2714                    Weekday::Sat,
2715                    Weekday::Sun,
2716                ]
2717                .iter()
2718                {
2719                    let d = NaiveDate::from_isoywd_opt(year, week, weekday);
2720                    if let Some(d) = d {
2721                        assert_eq!(d.weekday(), weekday);
2722                        let w = d.iso_week();
2723                        assert_eq!(w.year(), year);
2724                        assert_eq!(w.week(), week);
2725                    }
2726                }
2727            }
2728        }
2729
2730        for year in 2000..2401 {
2731            for month in 1..13 {
2732                for day in 1..32 {
2733                    let d = NaiveDate::from_ymd_opt(year, month, day);
2734                    if let Some(d) = d {
2735                        let w = d.iso_week();
2736                        let d_ = NaiveDate::from_isoywd_opt(w.year(), w.week(), d.weekday());
2737                        assert_eq!(d, d_.unwrap());
2738                    }
2739                }
2740            }
2741        }
2742    }
2743
2744    #[test]
2745    fn test_date_from_num_days_from_ce() {
2746        let from_ndays_from_ce = NaiveDate::from_num_days_from_ce_opt;
2747        assert_eq!(from_ndays_from_ce(1), Some(NaiveDate::from_ymd_opt(1, 1, 1).unwrap()));
2748        assert_eq!(from_ndays_from_ce(2), Some(NaiveDate::from_ymd_opt(1, 1, 2).unwrap()));
2749        assert_eq!(from_ndays_from_ce(31), Some(NaiveDate::from_ymd_opt(1, 1, 31).unwrap()));
2750        assert_eq!(from_ndays_from_ce(32), Some(NaiveDate::from_ymd_opt(1, 2, 1).unwrap()));
2751        assert_eq!(from_ndays_from_ce(59), Some(NaiveDate::from_ymd_opt(1, 2, 28).unwrap()));
2752        assert_eq!(from_ndays_from_ce(60), Some(NaiveDate::from_ymd_opt(1, 3, 1).unwrap()));
2753        assert_eq!(from_ndays_from_ce(365), Some(NaiveDate::from_ymd_opt(1, 12, 31).unwrap()));
2754        assert_eq!(from_ndays_from_ce(365 + 1), Some(NaiveDate::from_ymd_opt(2, 1, 1).unwrap()));
2755        assert_eq!(
2756            from_ndays_from_ce(365 * 2 + 1),
2757            Some(NaiveDate::from_ymd_opt(3, 1, 1).unwrap())
2758        );
2759        assert_eq!(
2760            from_ndays_from_ce(365 * 3 + 1),
2761            Some(NaiveDate::from_ymd_opt(4, 1, 1).unwrap())
2762        );
2763        assert_eq!(
2764            from_ndays_from_ce(365 * 4 + 2),
2765            Some(NaiveDate::from_ymd_opt(5, 1, 1).unwrap())
2766        );
2767        assert_eq!(
2768            from_ndays_from_ce(146097 + 1),
2769            Some(NaiveDate::from_ymd_opt(401, 1, 1).unwrap())
2770        );
2771        assert_eq!(
2772            from_ndays_from_ce(146097 * 5 + 1),
2773            Some(NaiveDate::from_ymd_opt(2001, 1, 1).unwrap())
2774        );
2775        assert_eq!(from_ndays_from_ce(719163), Some(NaiveDate::from_ymd_opt(1970, 1, 1).unwrap()));
2776        assert_eq!(from_ndays_from_ce(0), Some(NaiveDate::from_ymd_opt(0, 12, 31).unwrap())); // 1 BCE
2777        assert_eq!(from_ndays_from_ce(-365), Some(NaiveDate::from_ymd_opt(0, 1, 1).unwrap()));
2778        assert_eq!(from_ndays_from_ce(-366), Some(NaiveDate::from_ymd_opt(-1, 12, 31).unwrap())); // 2 BCE
2779
2780        for days in (-9999..10001).map(|x| x * 100) {
2781            assert_eq!(from_ndays_from_ce(days).map(|d| d.num_days_from_ce()), Some(days));
2782        }
2783
2784        assert_eq!(from_ndays_from_ce(NaiveDate::MIN.num_days_from_ce()), Some(NaiveDate::MIN));
2785        assert_eq!(from_ndays_from_ce(NaiveDate::MIN.num_days_from_ce() - 1), None);
2786        assert_eq!(from_ndays_from_ce(NaiveDate::MAX.num_days_from_ce()), Some(NaiveDate::MAX));
2787        assert_eq!(from_ndays_from_ce(NaiveDate::MAX.num_days_from_ce() + 1), None);
2788
2789        assert_eq!(from_ndays_from_ce(i32::MIN), None);
2790        assert_eq!(from_ndays_from_ce(i32::MAX), None);
2791    }
2792
2793    #[test]
2794    fn test_date_from_weekday_of_month_opt() {
2795        let ymwd = NaiveDate::from_weekday_of_month_opt;
2796        assert_eq!(ymwd(2018, 8, Weekday::Tue, 0), None);
2797        assert_eq!(
2798            ymwd(2018, 8, Weekday::Wed, 1),
2799            Some(NaiveDate::from_ymd_opt(2018, 8, 1).unwrap())
2800        );
2801        assert_eq!(
2802            ymwd(2018, 8, Weekday::Thu, 1),
2803            Some(NaiveDate::from_ymd_opt(2018, 8, 2).unwrap())
2804        );
2805        assert_eq!(
2806            ymwd(2018, 8, Weekday::Sun, 1),
2807            Some(NaiveDate::from_ymd_opt(2018, 8, 5).unwrap())
2808        );
2809        assert_eq!(
2810            ymwd(2018, 8, Weekday::Mon, 1),
2811            Some(NaiveDate::from_ymd_opt(2018, 8, 6).unwrap())
2812        );
2813        assert_eq!(
2814            ymwd(2018, 8, Weekday::Tue, 1),
2815            Some(NaiveDate::from_ymd_opt(2018, 8, 7).unwrap())
2816        );
2817        assert_eq!(
2818            ymwd(2018, 8, Weekday::Wed, 2),
2819            Some(NaiveDate::from_ymd_opt(2018, 8, 8).unwrap())
2820        );
2821        assert_eq!(
2822            ymwd(2018, 8, Weekday::Sun, 2),
2823            Some(NaiveDate::from_ymd_opt(2018, 8, 12).unwrap())
2824        );
2825        assert_eq!(
2826            ymwd(2018, 8, Weekday::Thu, 3),
2827            Some(NaiveDate::from_ymd_opt(2018, 8, 16).unwrap())
2828        );
2829        assert_eq!(
2830            ymwd(2018, 8, Weekday::Thu, 4),
2831            Some(NaiveDate::from_ymd_opt(2018, 8, 23).unwrap())
2832        );
2833        assert_eq!(
2834            ymwd(2018, 8, Weekday::Thu, 5),
2835            Some(NaiveDate::from_ymd_opt(2018, 8, 30).unwrap())
2836        );
2837        assert_eq!(
2838            ymwd(2018, 8, Weekday::Fri, 5),
2839            Some(NaiveDate::from_ymd_opt(2018, 8, 31).unwrap())
2840        );
2841        assert_eq!(ymwd(2018, 8, Weekday::Sat, 5), None);
2842    }
2843
2844    #[test]
2845    fn test_date_fields() {
2846        fn check(year: i32, month: u32, day: u32, ordinal: u32) {
2847            let d1 = NaiveDate::from_ymd_opt(year, month, day).unwrap();
2848            assert_eq!(d1.year(), year);
2849            assert_eq!(d1.month(), month);
2850            assert_eq!(d1.day(), day);
2851            assert_eq!(d1.ordinal(), ordinal);
2852
2853            let d2 = NaiveDate::from_yo_opt(year, ordinal).unwrap();
2854            assert_eq!(d2.year(), year);
2855            assert_eq!(d2.month(), month);
2856            assert_eq!(d2.day(), day);
2857            assert_eq!(d2.ordinal(), ordinal);
2858
2859            assert_eq!(d1, d2);
2860        }
2861
2862        check(2012, 1, 1, 1);
2863        check(2012, 1, 2, 2);
2864        check(2012, 2, 1, 32);
2865        check(2012, 2, 29, 60);
2866        check(2012, 3, 1, 61);
2867        check(2012, 4, 9, 100);
2868        check(2012, 7, 18, 200);
2869        check(2012, 10, 26, 300);
2870        check(2012, 12, 31, 366);
2871
2872        check(2014, 1, 1, 1);
2873        check(2014, 1, 2, 2);
2874        check(2014, 2, 1, 32);
2875        check(2014, 2, 28, 59);
2876        check(2014, 3, 1, 60);
2877        check(2014, 4, 10, 100);
2878        check(2014, 7, 19, 200);
2879        check(2014, 10, 27, 300);
2880        check(2014, 12, 31, 365);
2881    }
2882
2883    #[test]
2884    fn test_date_weekday() {
2885        assert_eq!(NaiveDate::from_ymd_opt(1582, 10, 15).unwrap().weekday(), Weekday::Fri);
2886        // May 20, 1875 = ISO 8601 reference date
2887        assert_eq!(NaiveDate::from_ymd_opt(1875, 5, 20).unwrap().weekday(), Weekday::Thu);
2888        assert_eq!(NaiveDate::from_ymd_opt(2000, 1, 1).unwrap().weekday(), Weekday::Sat);
2889    }
2890
2891    #[test]
2892    fn test_date_with_fields() {
2893        let d = NaiveDate::from_ymd_opt(2000, 2, 29).unwrap();
2894        assert_eq!(d.with_year(-400), Some(NaiveDate::from_ymd_opt(-400, 2, 29).unwrap()));
2895        assert_eq!(d.with_year(-100), None);
2896        assert_eq!(d.with_year(1600), Some(NaiveDate::from_ymd_opt(1600, 2, 29).unwrap()));
2897        assert_eq!(d.with_year(1900), None);
2898        assert_eq!(d.with_year(2000), Some(NaiveDate::from_ymd_opt(2000, 2, 29).unwrap()));
2899        assert_eq!(d.with_year(2001), None);
2900        assert_eq!(d.with_year(2004), Some(NaiveDate::from_ymd_opt(2004, 2, 29).unwrap()));
2901        assert_eq!(d.with_year(i32::MAX), None);
2902
2903        let d = NaiveDate::from_ymd_opt(2000, 4, 30).unwrap();
2904        assert_eq!(d.with_month(0), None);
2905        assert_eq!(d.with_month(1), Some(NaiveDate::from_ymd_opt(2000, 1, 30).unwrap()));
2906        assert_eq!(d.with_month(2), None);
2907        assert_eq!(d.with_month(3), Some(NaiveDate::from_ymd_opt(2000, 3, 30).unwrap()));
2908        assert_eq!(d.with_month(4), Some(NaiveDate::from_ymd_opt(2000, 4, 30).unwrap()));
2909        assert_eq!(d.with_month(12), Some(NaiveDate::from_ymd_opt(2000, 12, 30).unwrap()));
2910        assert_eq!(d.with_month(13), None);
2911        assert_eq!(d.with_month(u32::MAX), None);
2912
2913        let d = NaiveDate::from_ymd_opt(2000, 2, 8).unwrap();
2914        assert_eq!(d.with_day(0), None);
2915        assert_eq!(d.with_day(1), Some(NaiveDate::from_ymd_opt(2000, 2, 1).unwrap()));
2916        assert_eq!(d.with_day(29), Some(NaiveDate::from_ymd_opt(2000, 2, 29).unwrap()));
2917        assert_eq!(d.with_day(30), None);
2918        assert_eq!(d.with_day(u32::MAX), None);
2919
2920        let d = NaiveDate::from_ymd_opt(2000, 5, 5).unwrap();
2921        assert_eq!(d.with_ordinal(0), None);
2922        assert_eq!(d.with_ordinal(1), Some(NaiveDate::from_ymd_opt(2000, 1, 1).unwrap()));
2923        assert_eq!(d.with_ordinal(60), Some(NaiveDate::from_ymd_opt(2000, 2, 29).unwrap()));
2924        assert_eq!(d.with_ordinal(61), Some(NaiveDate::from_ymd_opt(2000, 3, 1).unwrap()));
2925        assert_eq!(d.with_ordinal(366), Some(NaiveDate::from_ymd_opt(2000, 12, 31).unwrap()));
2926        assert_eq!(d.with_ordinal(367), None);
2927        assert_eq!(d.with_ordinal(u32::MAX), None);
2928    }
2929
2930    #[test]
2931    fn test_date_num_days_from_ce() {
2932        assert_eq!(NaiveDate::from_ymd_opt(1, 1, 1).unwrap().num_days_from_ce(), 1);
2933
2934        for year in -9999..10001 {
2935            assert_eq!(
2936                NaiveDate::from_ymd_opt(year, 1, 1).unwrap().num_days_from_ce(),
2937                NaiveDate::from_ymd_opt(year - 1, 12, 31).unwrap().num_days_from_ce() + 1
2938            );
2939        }
2940    }
2941
2942    #[test]
2943    fn test_date_succ() {
2944        let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
2945        assert_eq!(ymd(2014, 5, 6).succ_opt(), Some(ymd(2014, 5, 7)));
2946        assert_eq!(ymd(2014, 5, 31).succ_opt(), Some(ymd(2014, 6, 1)));
2947        assert_eq!(ymd(2014, 12, 31).succ_opt(), Some(ymd(2015, 1, 1)));
2948        assert_eq!(ymd(2016, 2, 28).succ_opt(), Some(ymd(2016, 2, 29)));
2949        assert_eq!(ymd(NaiveDate::MAX.year(), 12, 31).succ_opt(), None);
2950    }
2951
2952    #[test]
2953    fn test_date_pred() {
2954        let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
2955        assert_eq!(ymd(2016, 3, 1).pred_opt(), Some(ymd(2016, 2, 29)));
2956        assert_eq!(ymd(2015, 1, 1).pred_opt(), Some(ymd(2014, 12, 31)));
2957        assert_eq!(ymd(2014, 6, 1).pred_opt(), Some(ymd(2014, 5, 31)));
2958        assert_eq!(ymd(2014, 5, 7).pred_opt(), Some(ymd(2014, 5, 6)));
2959        assert_eq!(ymd(NaiveDate::MIN.year(), 1, 1).pred_opt(), None);
2960    }
2961
2962    #[test]
2963    fn test_date_add() {
2964        fn check((y1, m1, d1): (i32, u32, u32), rhs: TimeDelta, ymd: Option<(i32, u32, u32)>) {
2965            let lhs = NaiveDate::from_ymd_opt(y1, m1, d1).unwrap();
2966            let sum = ymd.map(|(y, m, d)| NaiveDate::from_ymd_opt(y, m, d).unwrap());
2967            assert_eq!(lhs.checked_add_signed(rhs), sum);
2968            assert_eq!(lhs.checked_sub_signed(-rhs), sum);
2969        }
2970
2971        check((2014, 1, 1), TimeDelta::zero(), Some((2014, 1, 1)));
2972        check((2014, 1, 1), TimeDelta::seconds(86399), Some((2014, 1, 1)));
2973        // always round towards zero
2974        check((2014, 1, 1), TimeDelta::seconds(-86399), Some((2014, 1, 1)));
2975        check((2014, 1, 1), TimeDelta::days(1), Some((2014, 1, 2)));
2976        check((2014, 1, 1), TimeDelta::days(-1), Some((2013, 12, 31)));
2977        check((2014, 1, 1), TimeDelta::days(364), Some((2014, 12, 31)));
2978        check((2014, 1, 1), TimeDelta::days(365 * 4 + 1), Some((2018, 1, 1)));
2979        check((2014, 1, 1), TimeDelta::days(365 * 400 + 97), Some((2414, 1, 1)));
2980
2981        check((-7, 1, 1), TimeDelta::days(365 * 12 + 3), Some((5, 1, 1)));
2982
2983        // overflow check
2984        check((0, 1, 1), TimeDelta::days(MAX_DAYS_FROM_YEAR_0 as i64), Some((MAX_YEAR, 12, 31)));
2985        check((0, 1, 1), TimeDelta::days(MAX_DAYS_FROM_YEAR_0 as i64 + 1), None);
2986        check((0, 1, 1), TimeDelta::max_value(), None);
2987        check((0, 1, 1), TimeDelta::days(MIN_DAYS_FROM_YEAR_0 as i64), Some((MIN_YEAR, 1, 1)));
2988        check((0, 1, 1), TimeDelta::days(MIN_DAYS_FROM_YEAR_0 as i64 - 1), None);
2989        check((0, 1, 1), TimeDelta::min_value(), None);
2990    }
2991
2992    #[test]
2993    fn test_date_sub() {
2994        fn check((y1, m1, d1): (i32, u32, u32), (y2, m2, d2): (i32, u32, u32), diff: TimeDelta) {
2995            let lhs = NaiveDate::from_ymd_opt(y1, m1, d1).unwrap();
2996            let rhs = NaiveDate::from_ymd_opt(y2, m2, d2).unwrap();
2997            assert_eq!(lhs.signed_duration_since(rhs), diff);
2998            assert_eq!(rhs.signed_duration_since(lhs), -diff);
2999        }
3000
3001        check((2014, 1, 1), (2014, 1, 1), TimeDelta::zero());
3002        check((2014, 1, 2), (2014, 1, 1), TimeDelta::days(1));
3003        check((2014, 12, 31), (2014, 1, 1), TimeDelta::days(364));
3004        check((2015, 1, 3), (2014, 1, 1), TimeDelta::days(365 + 2));
3005        check((2018, 1, 1), (2014, 1, 1), TimeDelta::days(365 * 4 + 1));
3006        check((2414, 1, 1), (2014, 1, 1), TimeDelta::days(365 * 400 + 97));
3007
3008        check((MAX_YEAR, 12, 31), (0, 1, 1), TimeDelta::days(MAX_DAYS_FROM_YEAR_0 as i64));
3009        check((MIN_YEAR, 1, 1), (0, 1, 1), TimeDelta::days(MIN_DAYS_FROM_YEAR_0 as i64));
3010    }
3011
3012    #[test]
3013    fn test_date_add_days() {
3014        fn check((y1, m1, d1): (i32, u32, u32), rhs: Days, ymd: Option<(i32, u32, u32)>) {
3015            let lhs = NaiveDate::from_ymd_opt(y1, m1, d1).unwrap();
3016            let sum = ymd.map(|(y, m, d)| NaiveDate::from_ymd_opt(y, m, d).unwrap());
3017            assert_eq!(lhs.checked_add_days(rhs), sum);
3018        }
3019
3020        check((2014, 1, 1), Days::new(0), Some((2014, 1, 1)));
3021        // always round towards zero
3022        check((2014, 1, 1), Days::new(1), Some((2014, 1, 2)));
3023        check((2014, 1, 1), Days::new(364), Some((2014, 12, 31)));
3024        check((2014, 1, 1), Days::new(365 * 4 + 1), Some((2018, 1, 1)));
3025        check((2014, 1, 1), Days::new(365 * 400 + 97), Some((2414, 1, 1)));
3026
3027        check((-7, 1, 1), Days::new(365 * 12 + 3), Some((5, 1, 1)));
3028
3029        // overflow check
3030        check(
3031            (0, 1, 1),
3032            Days::new(MAX_DAYS_FROM_YEAR_0.try_into().unwrap()),
3033            Some((MAX_YEAR, 12, 31)),
3034        );
3035        check((0, 1, 1), Days::new(u64::try_from(MAX_DAYS_FROM_YEAR_0).unwrap() + 1), None);
3036    }
3037
3038    #[test]
3039    fn test_date_sub_days() {
3040        fn check((y1, m1, d1): (i32, u32, u32), (y2, m2, d2): (i32, u32, u32), diff: Days) {
3041            let lhs = NaiveDate::from_ymd_opt(y1, m1, d1).unwrap();
3042            let rhs = NaiveDate::from_ymd_opt(y2, m2, d2).unwrap();
3043            assert_eq!(lhs - diff, rhs);
3044        }
3045
3046        check((2014, 1, 1), (2014, 1, 1), Days::new(0));
3047        check((2014, 1, 2), (2014, 1, 1), Days::new(1));
3048        check((2014, 12, 31), (2014, 1, 1), Days::new(364));
3049        check((2015, 1, 3), (2014, 1, 1), Days::new(365 + 2));
3050        check((2018, 1, 1), (2014, 1, 1), Days::new(365 * 4 + 1));
3051        check((2414, 1, 1), (2014, 1, 1), Days::new(365 * 400 + 97));
3052
3053        check((MAX_YEAR, 12, 31), (0, 1, 1), Days::new(MAX_DAYS_FROM_YEAR_0.try_into().unwrap()));
3054        check((0, 1, 1), (MIN_YEAR, 1, 1), Days::new((-MIN_DAYS_FROM_YEAR_0).try_into().unwrap()));
3055    }
3056
3057    #[test]
3058    fn test_date_addassignment() {
3059        let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
3060        let mut date = ymd(2016, 10, 1);
3061        date += TimeDelta::days(10);
3062        assert_eq!(date, ymd(2016, 10, 11));
3063        date += TimeDelta::days(30);
3064        assert_eq!(date, ymd(2016, 11, 10));
3065    }
3066
3067    #[test]
3068    fn test_date_subassignment() {
3069        let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
3070        let mut date = ymd(2016, 10, 11);
3071        date -= TimeDelta::days(10);
3072        assert_eq!(date, ymd(2016, 10, 1));
3073        date -= TimeDelta::days(2);
3074        assert_eq!(date, ymd(2016, 9, 29));
3075    }
3076
3077    #[test]
3078    fn test_date_fmt() {
3079        assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(2012, 3, 4).unwrap()), "2012-03-04");
3080        assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(0, 3, 4).unwrap()), "0000-03-04");
3081        assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(-307, 3, 4).unwrap()), "-0307-03-04");
3082        assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(12345, 3, 4).unwrap()), "+12345-03-04");
3083
3084        assert_eq!(NaiveDate::from_ymd_opt(2012, 3, 4).unwrap().to_string(), "2012-03-04");
3085        assert_eq!(NaiveDate::from_ymd_opt(0, 3, 4).unwrap().to_string(), "0000-03-04");
3086        assert_eq!(NaiveDate::from_ymd_opt(-307, 3, 4).unwrap().to_string(), "-0307-03-04");
3087        assert_eq!(NaiveDate::from_ymd_opt(12345, 3, 4).unwrap().to_string(), "+12345-03-04");
3088
3089        // the format specifier should have no effect on `NaiveTime`
3090        assert_eq!(format!("{:+30?}", NaiveDate::from_ymd_opt(1234, 5, 6).unwrap()), "1234-05-06");
3091        assert_eq!(
3092            format!("{:30?}", NaiveDate::from_ymd_opt(12345, 6, 7).unwrap()),
3093            "+12345-06-07"
3094        );
3095    }
3096
3097    #[test]
3098    fn test_date_from_str() {
3099        // valid cases
3100        let valid = [
3101            "-0000000123456-1-2",
3102            "    -123456 - 1 - 2    ",
3103            "-12345-1-2",
3104            "-1234-12-31",
3105            "-7-6-5",
3106            "350-2-28",
3107            "360-02-29",
3108            "0360-02-29",
3109            "2015-2 -18",
3110            "2015-02-18",
3111            "+70-2-18",
3112            "+70000-2-18",
3113            "+00007-2-18",
3114        ];
3115        for &s in &valid {
3116            eprintln!("test_date_from_str valid {:?}", s);
3117            let d = match s.parse::<NaiveDate>() {
3118                Ok(d) => d,
3119                Err(e) => panic!("parsing `{}` has failed: {}", s, e),
3120            };
3121            eprintln!("d {:?} (NaiveDate)", d);
3122            let s_ = format!("{:?}", d);
3123            eprintln!("s_ {:?}", s_);
3124            // `s` and `s_` may differ, but `s.parse()` and `s_.parse()` must be same
3125            let d_ = match s_.parse::<NaiveDate>() {
3126                Ok(d) => d,
3127                Err(e) => {
3128                    panic!("`{}` is parsed into `{:?}`, but reparsing that has failed: {}", s, d, e)
3129                }
3130            };
3131            eprintln!("d_ {:?} (NaiveDate)", d_);
3132            assert!(
3133                d == d_,
3134                "`{}` is parsed into `{:?}`, but reparsed result \
3135                              `{:?}` does not match",
3136                s,
3137                d,
3138                d_
3139            );
3140        }
3141
3142        // some invalid cases
3143        // since `ParseErrorKind` is private, all we can do is to check if there was an error
3144        let invalid = [
3145            "",                     // empty
3146            "x",                    // invalid
3147            "Fri, 09 Aug 2013 GMT", // valid date, wrong format
3148            "Sat Jun 30 2012",      // valid date, wrong format
3149            "1441497364.649",       // valid datetime, wrong format
3150            "+1441497364.649",      // valid datetime, wrong format
3151            "+1441497364",          // valid datetime, wrong format
3152            "2014/02/03",           // valid date, wrong format
3153            "2014",                 // datetime missing data
3154            "2014-01",              // datetime missing data
3155            "2014-01-00",           // invalid day
3156            "2014-11-32",           // invalid day
3157            "2014-13-01",           // invalid month
3158            "2014-13-57",           // invalid month, day
3159            "9999999-9-9",          // invalid year (out of bounds)
3160        ];
3161        for &s in &invalid {
3162            eprintln!("test_date_from_str invalid {:?}", s);
3163            assert!(s.parse::<NaiveDate>().is_err());
3164        }
3165    }
3166
3167    #[test]
3168    fn test_date_parse_from_str() {
3169        let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
3170        assert_eq!(
3171            NaiveDate::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
3172            Ok(ymd(2014, 5, 7))
3173        ); // ignore time and offset
3174        assert_eq!(
3175            NaiveDate::parse_from_str("2015-W06-1=2015-033", "%G-W%V-%u = %Y-%j"),
3176            Ok(ymd(2015, 2, 2))
3177        );
3178        assert_eq!(
3179            NaiveDate::parse_from_str("Fri, 09 Aug 13", "%a, %d %b %y"),
3180            Ok(ymd(2013, 8, 9))
3181        );
3182        assert!(NaiveDate::parse_from_str("Sat, 09 Aug 2013", "%a, %d %b %Y").is_err());
3183        assert!(NaiveDate::parse_from_str("2014-57", "%Y-%m-%d").is_err());
3184        assert!(NaiveDate::parse_from_str("2014", "%Y").is_err()); // insufficient
3185
3186        assert_eq!(
3187            NaiveDate::parse_from_str("2020-01-0", "%Y-%W-%w").ok(),
3188            NaiveDate::from_ymd_opt(2020, 1, 12),
3189        );
3190
3191        assert_eq!(
3192            NaiveDate::parse_from_str("2019-01-0", "%Y-%W-%w").ok(),
3193            NaiveDate::from_ymd_opt(2019, 1, 13),
3194        );
3195    }
3196
3197    #[test]
3198    fn test_day_iterator_limit() {
3199        assert_eq!(
3200            NaiveDate::from_ymd_opt(MAX_YEAR, 12, 29).unwrap().iter_days().take(4).count(),
3201            2
3202        );
3203        assert_eq!(
3204            NaiveDate::from_ymd_opt(MIN_YEAR, 1, 3).unwrap().iter_days().rev().take(4).count(),
3205            2
3206        );
3207    }
3208
3209    #[test]
3210    fn test_week_iterator_limit() {
3211        assert_eq!(
3212            NaiveDate::from_ymd_opt(MAX_YEAR, 12, 12).unwrap().iter_weeks().take(4).count(),
3213            2
3214        );
3215        assert_eq!(
3216            NaiveDate::from_ymd_opt(MIN_YEAR, 1, 15).unwrap().iter_weeks().rev().take(4).count(),
3217            2
3218        );
3219    }
3220
3221    #[test]
3222    fn test_naiveweek() {
3223        let date = NaiveDate::from_ymd_opt(2022, 5, 18).unwrap();
3224        let asserts = [
3225            (Weekday::Mon, "Mon 2022-05-16", "Sun 2022-05-22"),
3226            (Weekday::Tue, "Tue 2022-05-17", "Mon 2022-05-23"),
3227            (Weekday::Wed, "Wed 2022-05-18", "Tue 2022-05-24"),
3228            (Weekday::Thu, "Thu 2022-05-12", "Wed 2022-05-18"),
3229            (Weekday::Fri, "Fri 2022-05-13", "Thu 2022-05-19"),
3230            (Weekday::Sat, "Sat 2022-05-14", "Fri 2022-05-20"),
3231            (Weekday::Sun, "Sun 2022-05-15", "Sat 2022-05-21"),
3232        ];
3233        for (start, first_day, last_day) in asserts {
3234            let week = date.week(start);
3235            let days = week.days();
3236            assert_eq!(Ok(week.first_day()), NaiveDate::parse_from_str(first_day, "%a %Y-%m-%d"));
3237            assert_eq!(Ok(week.last_day()), NaiveDate::parse_from_str(last_day, "%a %Y-%m-%d"));
3238            assert!(days.contains(&date));
3239        }
3240    }
3241
3242    #[test]
3243    fn test_naiveweek_min_max() {
3244        let date_max = NaiveDate::MAX;
3245        assert!(date_max.week(Weekday::Mon).first_day() <= date_max);
3246        let date_min = NaiveDate::MIN;
3247        assert!(date_min.week(Weekday::Mon).last_day() >= date_min);
3248    }
3249
3250    #[test]
3251    fn test_weeks_from() {
3252        // tests per: https://github.com/chronotope/chrono/issues/961
3253        // these internally use `weeks_from` via the parsing infrastructure
3254        assert_eq!(
3255            NaiveDate::parse_from_str("2020-01-0", "%Y-%W-%w").ok(),
3256            NaiveDate::from_ymd_opt(2020, 1, 12),
3257        );
3258        assert_eq!(
3259            NaiveDate::parse_from_str("2019-01-0", "%Y-%W-%w").ok(),
3260            NaiveDate::from_ymd_opt(2019, 1, 13),
3261        );
3262
3263        // direct tests
3264        for (y, starts_on) in &[
3265            (2019, Weekday::Tue),
3266            (2020, Weekday::Wed),
3267            (2021, Weekday::Fri),
3268            (2022, Weekday::Sat),
3269            (2023, Weekday::Sun),
3270            (2024, Weekday::Mon),
3271            (2025, Weekday::Wed),
3272            (2026, Weekday::Thu),
3273        ] {
3274            for day in &[
3275                Weekday::Mon,
3276                Weekday::Tue,
3277                Weekday::Wed,
3278                Weekday::Thu,
3279                Weekday::Fri,
3280                Weekday::Sat,
3281                Weekday::Sun,
3282            ] {
3283                assert_eq!(
3284                    NaiveDate::from_ymd_opt(*y, 1, 1).map(|d| d.weeks_from(*day)),
3285                    Some(if day == starts_on { 1 } else { 0 })
3286                );
3287
3288                // last day must always be in week 52 or 53
3289                assert!([52, 53]
3290                    .contains(&NaiveDate::from_ymd_opt(*y, 12, 31).unwrap().weeks_from(*day)),);
3291            }
3292        }
3293
3294        let base = NaiveDate::from_ymd_opt(2019, 1, 1).unwrap();
3295
3296        // 400 years covers all year types
3297        for day in &[
3298            Weekday::Mon,
3299            Weekday::Tue,
3300            Weekday::Wed,
3301            Weekday::Thu,
3302            Weekday::Fri,
3303            Weekday::Sat,
3304            Weekday::Sun,
3305        ] {
3306            // must always be below 54
3307            for dplus in 1..(400 * 366) {
3308                assert!((base + Days::new(dplus)).weeks_from(*day) < 54)
3309            }
3310        }
3311    }
3312
3313    #[test]
3314    fn test_with_0_overflow() {
3315        let dt = NaiveDate::from_ymd_opt(2023, 4, 18).unwrap();
3316        assert!(dt.with_month0(4294967295).is_none());
3317        assert!(dt.with_day0(4294967295).is_none());
3318        assert!(dt.with_ordinal0(4294967295).is_none());
3319    }
3320
3321    #[test]
3322    fn test_leap_year() {
3323        for year in 0..=MAX_YEAR {
3324            let date = NaiveDate::from_ymd_opt(year, 1, 1).unwrap();
3325            let is_leap = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
3326            assert_eq!(date.leap_year(), is_leap);
3327            assert_eq!(date.leap_year(), date.with_ordinal(366).is_some());
3328        }
3329    }
3330
3331    #[test]
3332    #[cfg(feature = "rkyv-validation")]
3333    fn test_rkyv_validation() {
3334        let date_min = NaiveDate::MIN;
3335        let bytes = rkyv::to_bytes::<_, 4>(&date_min).unwrap();
3336        assert_eq!(rkyv::from_bytes::<NaiveDate>(&bytes).unwrap(), date_min);
3337
3338        let date_max = NaiveDate::MAX;
3339        let bytes = rkyv::to_bytes::<_, 4>(&date_max).unwrap();
3340        assert_eq!(rkyv::from_bytes::<NaiveDate>(&bytes).unwrap(), date_max);
3341    }
3342
3343    //   MAX_YEAR-12-31 minus 0000-01-01
3344    // = (MAX_YEAR-12-31 minus 0000-12-31) + (0000-12-31 - 0000-01-01)
3345    // = MAX_YEAR * 365 + (# of leap years from 0001 to MAX_YEAR) + 365
3346    // = (MAX_YEAR + 1) * 365 + (# of leap years from 0001 to MAX_YEAR)
3347    const MAX_DAYS_FROM_YEAR_0: i32 =
3348        (MAX_YEAR + 1) * 365 + MAX_YEAR / 4 - MAX_YEAR / 100 + MAX_YEAR / 400;
3349
3350    //   MIN_YEAR-01-01 minus 0000-01-01
3351    // = MIN_YEAR * 365 + (# of leap years from MIN_YEAR to 0000)
3352    const MIN_DAYS_FROM_YEAR_0: i32 =
3353        MIN_YEAR * 365 + MIN_YEAR / 4 - MIN_YEAR / 100 + MIN_YEAR / 400;
3354
3355    // only used for testing, but duplicated in naive::datetime
3356    const MAX_BITS: usize = 44;
3357}