1 // This is a part of Chrono.
2 // See README.md and LICENSE.txt for details.
4 //! ISO 8601 calendar date without timezone.
7 use std
::ops
::{Add, Sub, AddAssign, SubAssign}
;
8 use num_traits
::ToPrimitive
;
9 use oldtime
::Duration
as OldDuration
;
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}
;
18 use super::internals
::{self, DateImpl, Of, Mdf, YearFlags}
;
20 const MAX_YEAR
: i32 = internals
::MAX_YEAR
;
21 const MIN_YEAR
: i32 = internals
::MIN_YEAR
;
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 +
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
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;
45 #[cfg(test)] // only used for testing, but duplicated in naive::datetime
46 const MAX_BITS
: usize = 44;
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.
55 /// The ISO 8601 **calendar date** follows the proleptic Gregorian calendar.
56 /// It is like a normal civil calendar but note some slight differences:
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).
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.)
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.
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:
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.
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.
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.
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.
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).
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
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*/ }
;
106 // as it is hard to verify year flags in `MIN_DATE` and `MAX_DATE`,
107 // we use a separate run-time 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());
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
);
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() {
130 Some(NaiveDate { ymdf: (year << 13) | (of as DateImpl) }
)
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())
141 /// Makes a new `NaiveDate` from the [calendar date](#calendar-date)
142 /// (year, month and day).
144 /// Panics on the out-of-range date, invalid month and/or day.
149 /// use chrono::{NaiveDate, Datelike, Weekday};
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
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")
165 /// Makes a new `NaiveDate` from the [calendar date](#calendar-date)
166 /// (year, month and day).
168 /// Returns `None` on the out-of-range date, invalid month and/or day.
173 /// use chrono::NaiveDate;
175 /// let from_ymd_opt = NaiveDate::from_ymd_opt;
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());
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
))
189 /// Makes a new `NaiveDate` from the [ordinal date](#ordinal-date)
190 /// (year and day of the year).
192 /// Panics on the out-of-range date and/or invalid day of year.
197 /// use chrono::{NaiveDate, Datelike, Weekday};
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
209 pub fn from_yo(year
: i32, ordinal
: u32) -> NaiveDate
{
210 NaiveDate
::from_yo_opt(year
, ordinal
).expect("invalid or out-of-range date")
213 /// Makes a new `NaiveDate` from the [ordinal date](#ordinal-date)
214 /// (year and day of the year).
216 /// Returns `None` on the out-of-range date and/or invalid day of year.
221 /// use chrono::NaiveDate;
223 /// let from_yo_opt = NaiveDate::from_yo_opt;
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());
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
))
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.
242 /// Panics on the out-of-range date and/or invalid week number.
247 /// use chrono::{NaiveDate, Datelike, Weekday};
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
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")
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.
267 /// Returns `None` on the out-of-range date and/or invalid week number.
272 /// use chrono::{NaiveDate, Weekday};
274 /// let from_ymd = NaiveDate::from_ymd;
275 /// let from_isoywd_opt = NaiveDate::from_isoywd_opt;
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);
282 /// assert_eq!(from_isoywd_opt(400000, 10, Weekday::Fri), None);
283 /// assert_eq!(from_isoywd_opt(-400000, 10, Weekday::Sat), None);
286 /// The year number of ISO week date may differ from that of the calendar date.
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)));
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)));
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
,
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
))
333 /// Makes a new `NaiveDate` from the number of days since January 1, 1 (Day 1)
334 /// in the proleptic Gregorian calendar.
336 /// Panics on the out-of-range date.
341 /// use chrono::{NaiveDate, Datelike, Weekday};
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);
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.)
361 /// use chrono::NaiveDate;
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)
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));
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));
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")
381 /// Makes a new `NaiveDate` from the number of days since January 1, 1 (Day 1)
382 /// in the proleptic Gregorian calendar.
384 /// Returns `None` on the out-of-range date.
389 /// use chrono::NaiveDate;
391 /// let from_ndays_opt = NaiveDate::from_num_days_from_ce_opt;
392 /// let from_ymd = NaiveDate::from_ymd;
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);
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
))
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.
417 /// use chrono::NaiveDate;
419 /// let parse_from_str = NaiveDate::parse_from_str;
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)));
427 /// Time and offset is ignored for the purpose of parsing.
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)));
436 /// Out-of-bound dates or insufficient fields are errors.
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());
445 /// All parsed fields should be consistent to each other, otherwise it's an error.
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());
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()
458 /// Makes a new `NaiveDateTime` from the current date and given `NaiveTime`.
463 /// use chrono::{NaiveDate, NaiveTime, NaiveDateTime};
465 /// let d = NaiveDate::from_ymd(2015, 6, 3);
466 /// let t = NaiveTime::from_hms_milli(12, 34, 56, 789);
468 /// let dt: NaiveDateTime = d.and_time(t);
469 /// assert_eq!(dt.date(), d);
470 /// assert_eq!(dt.time(), t);
473 pub fn and_time(&self, time
: NaiveTime
) -> NaiveDateTime
{
474 NaiveDateTime
::new(*self, time
)
477 /// Makes a new `NaiveDateTime` from the current date, hour, minute and second.
479 /// No [leap second](./struct.NaiveTime.html#leap-second-handling) is allowed here;
480 /// use `NaiveDate::and_hms_*` methods with a subsecond parameter instead.
482 /// Panics on invalid hour, minute and/or second.
487 /// use chrono::{NaiveDate, NaiveDateTime, Datelike, Timelike, Weekday};
489 /// let d = NaiveDate::from_ymd(2015, 6, 3);
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);
497 pub fn and_hms(&self, hour
: u32, min
: u32, sec
: u32) -> NaiveDateTime
{
498 self.and_hms_opt(hour
, min
, sec
).expect("invalid time")
501 /// Makes a new `NaiveDateTime` from the current date, hour, minute and second.
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.
506 /// Returns `None` on invalid hour, minute and/or second.
511 /// use chrono::NaiveDate;
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());
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
))
524 /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and millisecond.
526 /// The millisecond part can exceed 1,000
527 /// in order to represent the [leap second](./struct.NaiveTime.html#leap-second-handling).
529 /// Panics on invalid hour, minute, second and/or millisecond.
534 /// use chrono::{NaiveDate, NaiveDateTime, Datelike, Timelike, Weekday};
536 /// let d = NaiveDate::from_ymd(2015, 6, 3);
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);
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")
549 /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and millisecond.
551 /// The millisecond part can exceed 1,000
552 /// in order to represent the [leap second](./struct.NaiveTime.html#leap-second-handling).
554 /// Returns `None` on invalid hour, minute, second and/or millisecond.
559 /// use chrono::NaiveDate;
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());
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
))
575 /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and microsecond.
577 /// The microsecond part can exceed 1,000,000
578 /// in order to represent the [leap second](./struct.NaiveTime.html#leap-second-handling).
580 /// Panics on invalid hour, minute, second and/or microsecond.
585 /// use chrono::{NaiveDate, NaiveDateTime, Datelike, Timelike, Weekday};
587 /// let d = NaiveDate::from_ymd(2015, 6, 3);
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);
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")
600 /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and microsecond.
602 /// The microsecond part can exceed 1,000,000
603 /// in order to represent the [leap second](./struct.NaiveTime.html#leap-second-handling).
605 /// Returns `None` on invalid hour, minute, second and/or microsecond.
610 /// use chrono::NaiveDate;
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());
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
))
626 /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and nanosecond.
628 /// The nanosecond part can exceed 1,000,000,000
629 /// in order to represent the [leap second](./struct.NaiveTime.html#leap-second-handling).
631 /// Panics on invalid hour, minute, second and/or nanosecond.
636 /// use chrono::{NaiveDate, NaiveDateTime, Datelike, Timelike, Weekday};
638 /// let d = NaiveDate::from_ymd(2015, 6, 3);
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);
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")
651 /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and nanosecond.
653 /// The nanosecond part can exceed 1,000,000,000
654 /// in order to represent the [leap second](./struct.NaiveTime.html#leap-second-handling).
656 /// Returns `None` on invalid hour, minute, second and/or nanosecond.
661 /// use chrono::NaiveDate;
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());
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
))
677 /// Returns the packed month-day-flags.
679 fn mdf(&self) -> Mdf
{
683 /// Returns the packed ordinal-flags.
686 Of((self.ymdf
& 0b1_1111_1111_1111) as u32)
689 /// Makes a new `NaiveDate` with the packed month-day-flags changed.
691 /// Returns `None` when the resulting `NaiveDate` would be invalid.
693 fn with_mdf(&self, mdf
: Mdf
) -> Option
<NaiveDate
> {
694 self.with_of(mdf
.to_of())
697 /// Makes a new `NaiveDate` with the packed ordinal-flags changed.
699 /// Returns `None` when the resulting `NaiveDate` would be invalid.
701 fn with_of(&self, of
: Of
) -> Option
<NaiveDate
> {
704 Some(NaiveDate { ymdf: (self.ymdf & !0b1_1111_1111_1111) | of as DateImpl }
)
710 /// Makes a new `NaiveDate` for the next calendar date.
712 /// Panics when `self` is the last representable date.
717 /// use chrono::NaiveDate;
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));
724 pub fn succ(&self) -> NaiveDate
{
725 self.succ_opt().expect("out of bound")
728 /// Makes a new `NaiveDate` for the next calendar date.
730 /// Returns `None` when `self` is the last representable date.
735 /// use chrono::NaiveDate;
736 /// use chrono::naive::MAX_DATE;
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);
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))
747 /// Makes a new `NaiveDate` for the previous calendar date.
749 /// Panics when `self` is the first representable date.
754 /// use chrono::NaiveDate;
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));
761 pub fn pred(&self) -> NaiveDate
{
762 self.pred_opt().expect("out of bound")
765 /// Makes a new `NaiveDate` for the previous calendar date.
767 /// Returns `None` when `self` is the first representable date.
772 /// use chrono::NaiveDate;
773 /// use chrono::naive::MIN_DATE;
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);
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))
784 /// Adds the `days` part of given `Duration` to the current date.
786 /// Returns `None` when it will result in overflow.
791 /// # extern crate chrono; extern crate time; fn main() {
792 /// use chrono::NaiveDate;
793 /// use chrono::naive::MAX_DATE;
794 /// use time::Duration;
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);
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
;
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
))
820 /// Subtracts the `days` part of given `Duration` from the current date.
822 /// Returns `None` when it will result in overflow.
827 /// # extern crate chrono; extern crate time; fn main() {
828 /// use chrono::NaiveDate;
829 /// use chrono::naive::MIN_DATE;
830 /// use time::Duration;
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);
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
;
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
))
856 /// Subtracts another `NaiveDate` from the current date.
857 /// Returns a `Duration` of integral numbers.
859 /// This does not overflow or underflow at all,
860 /// as all possible output fits in the range of `Duration`.
865 /// # extern crate chrono; extern crate time; fn main() {
866 /// use chrono::NaiveDate;
867 /// use time::Duration;
869 /// let from_ymd = NaiveDate::from_ymd;
870 /// let since = NaiveDate::signed_duration_since;
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));
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 +
892 /// Formats the date with the specified formatting items.
893 /// Otherwise it is same to the ordinary `format` method.
895 /// The `Iterator` of items should be `Clone`able,
896 /// since the resulting `DelayedFormat` value may be formatted multiple times.
901 /// use chrono::NaiveDate;
902 /// use chrono::format::strftime::StrftimeItems;
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");
910 /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
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");
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
)
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.
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.)
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.
942 /// use chrono::NaiveDate;
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");
949 /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
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");
958 pub fn format
<'a
>(&self, fmt
: &'a
str) -> DelayedFormat
<StrftimeItems
<'a
>> {
959 self.format_with_items(StrftimeItems
::new(fmt
))
963 impl Datelike
for NaiveDate
{
964 /// Returns the year number in the [calendar date](#calendar-date).
969 /// use chrono::{NaiveDate, Datelike};
971 /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).year(), 2015);
972 /// assert_eq!(NaiveDate::from_ymd(-308, 3, 14).year(), -308); // 309 BCE
975 fn year(&self) -> i32 {
979 /// Returns the month number starting from 1.
981 /// The return value ranges from 1 to 12.
986 /// use chrono::{NaiveDate, Datelike};
988 /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).month(), 9);
989 /// assert_eq!(NaiveDate::from_ymd(-308, 3, 14).month(), 3);
992 fn month(&self) -> u32 {
996 /// Returns the month number starting from 0.
998 /// The return value ranges from 0 to 11.
1003 /// use chrono::{NaiveDate, Datelike};
1005 /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).month0(), 8);
1006 /// assert_eq!(NaiveDate::from_ymd(-308, 3, 14).month0(), 2);
1009 fn month0(&self) -> u32 {
1010 self.mdf().month() - 1
1013 /// Returns the day of month starting from 1.
1015 /// The return value ranges from 1 to 31. (The last day of month differs by months.)
1020 /// use chrono::{NaiveDate, Datelike};
1022 /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).day(), 8);
1023 /// assert_eq!(NaiveDate::from_ymd(-308, 3, 14).day(), 14);
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.)
1031 /// use chrono::{NaiveDate, Datelike};
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);
1038 /// // ...is preceded by the last day of the original month
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);
1049 fn day(&self) -> u32 {
1053 /// Returns the day of month starting from 0.
1055 /// The return value ranges from 0 to 30. (The last day of month differs by months.)
1060 /// use chrono::{NaiveDate, Datelike};
1062 /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).day0(), 7);
1063 /// assert_eq!(NaiveDate::from_ymd(-308, 3, 14).day0(), 13);
1066 fn day0(&self) -> u32 {
1067 self.mdf().day() - 1
1070 /// Returns the day of year starting from 1.
1072 /// The return value ranges from 1 to 366. (The last day of year differs by years.)
1077 /// use chrono::{NaiveDate, Datelike};
1079 /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).ordinal(), 251);
1080 /// assert_eq!(NaiveDate::from_ymd(-308, 3, 14).ordinal(), 74);
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.)
1088 /// use chrono::{NaiveDate, Datelike};
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);
1094 /// // ...is preceded by the last day of the original year
1095 /// d.pred().ordinal()
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);
1105 fn ordinal(&self) -> u32 {
1109 /// Returns the day of year starting from 0.
1111 /// The return value ranges from 0 to 365. (The last day of year differs by years.)
1116 /// use chrono::{NaiveDate, Datelike};
1118 /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).ordinal0(), 250);
1119 /// assert_eq!(NaiveDate::from_ymd(-308, 3, 14).ordinal0(), 73);
1122 fn ordinal0(&self) -> u32 {
1123 self.of().ordinal() - 1
1126 /// Returns the day of week.
1131 /// use chrono::{NaiveDate, Datelike, Weekday};
1133 /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).weekday(), Weekday::Tue);
1134 /// assert_eq!(NaiveDate::from_ymd(-308, 3, 14).weekday(), Weekday::Fri);
1137 fn weekday(&self) -> Weekday
{
1142 fn iso_week(&self) -> IsoWeek
{
1143 isoweek
::iso_week_from_yof(self.year(), self.of())
1146 /// Makes a new `NaiveDate` with the year number changed.
1148 /// Returns `None` when the resulting `NaiveDate` would be invalid.
1153 /// use chrono::{NaiveDate, Datelike};
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)));
1161 /// A leap day (February 29) is a good example that this method can return `None`.
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());
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();
1173 // adjust the flags as needed
1174 let flags
= YearFlags
::from_year(year
);
1175 let mdf
= mdf
.with_flags(flags
);
1177 NaiveDate
::from_mdf(year
, mdf
)
1180 /// Makes a new `NaiveDate` with the month number (starting from 1) changed.
1182 /// Returns `None` when the resulting `NaiveDate` would be invalid.
1187 /// use chrono::{NaiveDate, Datelike};
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
1195 fn with_month(&self, month
: u32) -> Option
<NaiveDate
> {
1196 self.with_mdf(self.mdf().with_month(month
))
1199 /// Makes a new `NaiveDate` with the month number (starting from 0) changed.
1201 /// Returns `None` when the resulting `NaiveDate` would be invalid.
1206 /// use chrono::{NaiveDate, Datelike};
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
1214 fn with_month0(&self, month0
: u32) -> Option
<NaiveDate
> {
1215 self.with_mdf(self.mdf().with_month(month0
+ 1))
1218 /// Makes a new `NaiveDate` with the day of month (starting from 1) changed.
1220 /// Returns `None` when the resulting `NaiveDate` would be invalid.
1225 /// use chrono::{NaiveDate, Datelike};
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
1233 fn with_day(&self, day
: u32) -> Option
<NaiveDate
> {
1234 self.with_mdf(self.mdf().with_day(day
))
1237 /// Makes a new `NaiveDate` with the day of month (starting from 0) changed.
1239 /// Returns `None` when the resulting `NaiveDate` would be invalid.
1244 /// use chrono::{NaiveDate, Datelike};
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
1252 fn with_day0(&self, day0
: u32) -> Option
<NaiveDate
> {
1253 self.with_mdf(self.mdf().with_day(day0
+ 1))
1256 /// Makes a new `NaiveDate` with the day of year (starting from 1) changed.
1258 /// Returns `None` when the resulting `NaiveDate` would be invalid.
1263 /// use chrono::{NaiveDate, Datelike};
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
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)));
1276 fn with_ordinal(&self, ordinal
: u32) -> Option
<NaiveDate
> {
1277 self.with_of(self.of().with_ordinal(ordinal
))
1280 /// Makes a new `NaiveDate` with the day of year (starting from 0) changed.
1282 /// Returns `None` when the resulting `NaiveDate` would be invalid.
1287 /// use chrono::{NaiveDate, Datelike};
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
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)));
1300 fn with_ordinal0(&self, ordinal0
: u32) -> Option
<NaiveDate
> {
1301 self.with_of(self.of().with_ordinal(ordinal0
+ 1))
1305 /// An addition of `Duration` to `NaiveDate` discards the fractional days,
1306 /// rounding to the closest integral number of days towards `Duration::zero()`.
1308 /// Panics on underflow or overflow.
1309 /// Use [`NaiveDate::checked_add_signed`](#method.checked_add_signed) to detect that.
1314 /// # extern crate chrono; extern crate time; fn main() {
1315 /// use chrono::NaiveDate;
1316 /// use time::Duration;
1318 /// let from_ymd = NaiveDate::from_ymd;
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));
1330 impl Add
<OldDuration
> for NaiveDate
{
1331 type Output
= NaiveDate
;
1334 fn add(self, rhs
: OldDuration
) -> NaiveDate
{
1335 self.checked_add_signed(rhs
).expect("`NaiveDate + Duration` overflowed")
1339 impl AddAssign
<OldDuration
> for NaiveDate
{
1341 fn add_assign(&mut self, rhs
: OldDuration
) {
1342 *self = self.add(rhs
);
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`.
1350 /// Panics on underflow or overflow.
1351 /// Use [`NaiveDate::checked_sub_signed`](#method.checked_sub_signed) to detect that.
1356 /// # extern crate chrono; extern crate time; fn main() {
1357 /// use chrono::NaiveDate;
1358 /// use time::Duration;
1360 /// let from_ymd = NaiveDate::from_ymd;
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));
1372 impl Sub
<OldDuration
> for NaiveDate
{
1373 type Output
= NaiveDate
;
1376 fn sub(self, rhs
: OldDuration
) -> NaiveDate
{
1377 self.checked_sub_signed(rhs
).expect("`NaiveDate - Duration` overflowed")
1381 impl SubAssign
<OldDuration
> for NaiveDate
{
1383 fn sub_assign(&mut self, rhs
: OldDuration
) {
1384 *self = self.sub(rhs
);
1388 /// Subtracts another `NaiveDate` from the current date.
1389 /// Returns a `Duration` of integral numbers.
1391 /// This does not overflow or underflow at all,
1392 /// as all possible output fits in the range of `Duration`.
1394 /// The implementation is a wrapper around
1395 /// [`NaiveDate::signed_duration_since`](#method.signed_duration_since).
1400 /// # extern crate chrono; extern crate time; fn main() {
1401 /// use chrono::NaiveDate;
1402 /// use time::Duration;
1404 /// let from_ymd = NaiveDate::from_ymd;
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));
1415 impl Sub
<NaiveDate
> for NaiveDate
{
1416 type Output
= OldDuration
;
1419 fn sub(self, rhs
: NaiveDate
) -> OldDuration
{
1420 self.signed_duration_since(rhs
)
1424 /// The `Debug` output of the naive date `d` is same to
1425 /// [`d.format("%Y-%m-%d")`](../format/strftime/index.html).
1427 /// The string printed can be readily parsed via the `parse` method on `str`.
1432 /// use chrono::NaiveDate;
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");
1439 /// ISO 8601 requires an explicit sign for years before 1 BCE or after 9999 CE.
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");
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())
1453 // ISO 8601 requires the explicit sign for out-of-range years
1454 write
!(f
, "{:+05}-{:02}-{:02}", year
, mdf
.month(), mdf
.day())
1459 /// The `Display` output of the naive date `d` is same to
1460 /// [`d.format("%Y-%m-%d")`](../format/strftime/index.html).
1462 /// The string printed can be readily parsed via the `parse` method on `str`.
1467 /// use chrono::NaiveDate;
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");
1474 /// ISO 8601 requires an explicit sign for years before 1 BCE or after 9999 CE.
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");
1481 impl fmt
::Display
for NaiveDate
{
1482 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result { fmt::Debug::fmt(self, f) }
1485 /// Parsing a `str` into a `NaiveDate` uses the same format,
1486 /// [`%Y-%m-%d`](../format/strftime/index.html), as in `Debug` and `Display`.
1491 /// use chrono::NaiveDate;
1493 /// let d = NaiveDate::from_ymd(2015, 9, 18);
1494 /// assert_eq!("2015-09-18".parse::<NaiveDate>(), Ok(d));
1496 /// let d = NaiveDate::from_ymd(12345, 6, 7);
1497 /// assert_eq!("+12345-6-7".parse::<NaiveDate>(), Ok(d));
1499 /// assert!("foo".parse::<NaiveDate>().is_err());
1501 impl str::FromStr
for NaiveDate
{
1502 type Err
= ParseError
;
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
),
1514 let mut parsed
= Parsed
::new();
1515 try
!(parse(&mut parsed
, s
, ITEMS
.iter().cloned()));
1516 parsed
.to_naive_date()
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
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()));
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
1540 use std
::{i32, i64}
;
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));
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());
1571 #[cfg(feature = "rustc-serialize")]
1572 mod rustc_serialize
{
1573 use super::NaiveDate
;
1574 use rustc_serialize
::{Encodable, Encoder, Decodable, Decoder}
;
1576 impl Encodable
for NaiveDate
{
1577 fn encode
<S
: Encoder
>(&self, s
: &mut S
) -> Result
<(), S
::Error
> {
1578 format
!("{:?}", self).encode(s
)
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"))
1588 #[cfg(test)] use rustc_serialize::json;
1591 fn test_encodable() {
1592 super::test_encodable_json(json
::encode
);
1596 fn test_decodable() {
1597 super::test_decodable_json(json
::decode
);
1601 #[cfg(feature = "serde")]
1604 use super::NaiveDate
;
1605 use serdelib
::{ser, de}
;
1607 // TODO not very optimized for space (binary formats would want something better)
1609 impl ser
::Serialize
for NaiveDate
{
1610 fn serialize
<S
>(&self, serializer
: S
) -> Result
<S
::Ok
, S
::Error
>
1611 where S
: ser
::Serializer
1613 struct FormatWrapped
<'a
, D
: 'a
> {
1617 impl<'a
, D
: fmt
::Debug
> fmt
::Display
for FormatWrapped
<'a
, D
> {
1618 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
1623 serializer
.collect_str(&FormatWrapped { inner: &self }
)
1627 struct NaiveDateVisitor
;
1629 impl<'de
> de
::Visitor
<'de
> for NaiveDateVisitor
{
1630 type Value
= NaiveDate
;
1632 fn expecting(&self, formatter
: &mut fmt
::Formatter
) -> fmt
::Result
1634 write
!(formatter
, "a formatted date string")
1637 fn visit_str
<E
>(self, value
: &str) -> Result
<NaiveDate
, E
>
1640 value
.parse().map_err(|err
| E
::custom(format
!("{}", err
)))
1644 impl<'de
> de
::Deserialize
<'de
> for NaiveDate
{
1645 fn deserialize
<D
>(deserializer
: D
) -> Result
<Self, D
::Error
>
1646 where D
: de
::Deserializer
<'de
>
1648 deserializer
.deserialize_str(NaiveDateVisitor
)
1652 #[cfg(test)] extern crate serde_json;
1653 #[cfg(test)] extern crate bincode;
1656 fn test_serde_serialize() {
1657 super::test_encodable_json(self::serde_json
::to_string
);
1661 fn test_serde_deserialize() {
1662 super::test_decodable_json(|input
| self::serde_json
::from_str(&input
));
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}
;
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
);
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
;
1688 fn test_date_from_ymd() {
1689 let ymd_opt
= |y
,m
,d
| NaiveDate
::from_ymd_opt(y
, m
, d
);
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());
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
);
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
);
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
);
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
);
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
);
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)));
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
);
1763 fn test_date_from_isoywd_and_iso_week() {
1764 for year
in 2000..2401 {
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
);
1771 assert_eq
!(d
.weekday(), weekday
);
1772 let w
= d
.iso_week();
1773 assert_eq
!(w
.year(), year
);
1774 assert_eq
!(w
.week(), week
);
1780 for year
in 2000..2401 {
1781 for month
in 1..13 {
1783 let d
= NaiveDate
::from_ymd_opt(year
, month
, day
);
1786 let w
= d
.iso_week();
1787 let d_
= NaiveDate
::from_isoywd(w
.year(), w
.week(), d
.weekday());
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
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
));
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
);
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
);
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
);
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);
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);
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
);
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
);
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
);
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
);
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
);
1913 fn test_date_num_days_from_ce() {
1914 assert_eq
!(NaiveDate
::from_ymd(1, 1, 1).num_days_from_ce(), 1);
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);
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
);
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
);
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
);
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)));
1961 check((-7, 1, 1), Duration
::days(365*12 + 3), Some((5, 1, 1)));
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
);
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
);
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));
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));
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));
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));
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");
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");
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");
2030 fn test_date_from_str() {
2033 "-0000000123456-1-2",
2034 " -123456 - 1 - 2 ",
2047 let d
= match s
.parse
::<NaiveDate
>() {
2049 Err(e
) => panic
!("parsing `{}` has failed: {}", s
, e
)
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
>() {
2055 Err(e
) => panic
!("`{}` is parsed into `{:?}`, but reparsing that has failed: {}",
2058 assert
!(d
== d_
, "`{}` is parsed into `{:?}`, but reparsed result \
2059 `{:?}` does not match", s
, d
, d_
);
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
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
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");
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");
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");