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