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