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