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