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