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