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