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