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