1 // This is a part of Chrono.
2 // See README.md and LICENSE.txt for details.
3
4 //! ISO 8601 date and time without timezone.
5
6 #[cfg(any(feature = "alloc", feature = "std", test))]
7 use core::borrow::Borrow;
8 use core::ops::{Add, AddAssign, Sub, SubAssign};
9 use core::{fmt, hash, str};
10 use num_traits::ToPrimitive;
11 use oldtime::Duration as OldDuration;
12
13 use div::div_mod_floor;
14 #[cfg(any(feature = "alloc", feature = "std", test))]
15 use format::DelayedFormat;
16 use format::{parse, ParseError, ParseResult, Parsed, StrftimeItems};
17 use format::{Fixed, Item, Numeric, Pad};
18 use naive::date::{MAX_DATE, MIN_DATE};
19 use naive::time::{MAX_TIME, MIN_TIME};
20 use naive::{IsoWeek, NaiveDate, NaiveTime};
21 use {Datelike, Timelike, Weekday};
22
23 /// The tight upper bound guarantees that a duration with `|Duration| >= 2^MAX_SECS_BITS`
24 /// will always overflow the addition with any date and time type.
25 ///
26 /// So why is this needed? `Duration::seconds(rhs)` may overflow, and we don't have
27 /// an alternative returning `Option` or `Result`. Thus we need some early bound to avoid
28 /// touching that call when we are already sure that it WILL overflow...
29 const MAX_SECS_BITS: usize = 44;
30
31 /// The minimum possible `NaiveDateTime`.
32 pub const MIN_DATETIME: NaiveDateTime = NaiveDateTime { date: MIN_DATE, time: MIN_TIME };
33 /// The maximum possible `NaiveDateTime`.
34 pub const MAX_DATETIME: NaiveDateTime = NaiveDateTime { date: MAX_DATE, time: MAX_TIME };
35
36 /// ISO 8601 combined date and time without timezone.
37 ///
38 /// # Example
39 ///
40 /// `NaiveDateTime` is commonly created from [`NaiveDate`](./struct.NaiveDate.html).
41 ///
42 /// ~~~~
43 /// use chrono::{NaiveDate, NaiveDateTime};
44 ///
45 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2016, 7, 8).and_hms(9, 10, 11);
46 /// # let _ = dt;
47 /// ~~~~
48 ///
49 /// You can use typical [date-like](../trait.Datelike.html) and
50 /// [time-like](../trait.Timelike.html) methods,
51 /// provided that relevant traits are in the scope.
52 ///
53 /// ~~~~
54 /// # use chrono::{NaiveDate, NaiveDateTime};
55 /// # let dt: NaiveDateTime = NaiveDate::from_ymd(2016, 7, 8).and_hms(9, 10, 11);
56 /// use chrono::{Datelike, Timelike, Weekday};
57 ///
58 /// assert_eq!(dt.weekday(), Weekday::Fri);
59 /// assert_eq!(dt.num_seconds_from_midnight(), 33011);
60 /// ~~~~
61 #[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
62 pub struct NaiveDateTime {
63 date: NaiveDate,
64 time: NaiveTime,
65 }
66
67 impl NaiveDateTime {
68 /// Makes a new `NaiveDateTime` from date and time components.
69 /// Equivalent to [`date.and_time(time)`](./struct.NaiveDate.html#method.and_time)
70 /// and many other helper constructors on `NaiveDate`.
71 ///
72 /// # Example
73 ///
74 /// ~~~~
75 /// use chrono::{NaiveDate, NaiveTime, NaiveDateTime};
76 ///
77 /// let d = NaiveDate::from_ymd(2015, 6, 3);
78 /// let t = NaiveTime::from_hms_milli(12, 34, 56, 789);
79 ///
80 /// let dt = NaiveDateTime::new(d, t);
81 /// assert_eq!(dt.date(), d);
82 /// assert_eq!(dt.time(), t);
83 /// ~~~~
84 #[inline]
new(date: NaiveDate, time: NaiveTime) -> NaiveDateTime85 pub fn new(date: NaiveDate, time: NaiveTime) -> NaiveDateTime {
86 NaiveDateTime { date: date, time: time }
87 }
88
89 /// Makes a new `NaiveDateTime` corresponding to a UTC date and time,
90 /// from the number of non-leap seconds
91 /// since the midnight UTC on January 1, 1970 (aka "UNIX timestamp")
92 /// and the number of nanoseconds since the last whole non-leap second.
93 ///
94 /// For a non-naive version of this function see
95 /// [`TimeZone::timestamp`](../offset/trait.TimeZone.html#method.timestamp).
96 ///
97 /// The nanosecond part can exceed 1,000,000,000 in order to represent the
98 /// [leap second](./struct.NaiveTime.html#leap-second-handling). (The true "UNIX
99 /// timestamp" cannot represent a leap second unambiguously.)
100 ///
101 /// Panics on the out-of-range number of seconds and/or invalid nanosecond.
102 ///
103 /// # Example
104 ///
105 /// ~~~~
106 /// use chrono::{NaiveDateTime, NaiveDate};
107 ///
108 /// let dt = NaiveDateTime::from_timestamp(0, 42_000_000);
109 /// assert_eq!(dt, NaiveDate::from_ymd(1970, 1, 1).and_hms_milli(0, 0, 0, 42));
110 ///
111 /// let dt = NaiveDateTime::from_timestamp(1_000_000_000, 0);
112 /// assert_eq!(dt, NaiveDate::from_ymd(2001, 9, 9).and_hms(1, 46, 40));
113 /// ~~~~
114 #[inline]
from_timestamp(secs: i64, nsecs: u32) -> NaiveDateTime115 pub fn from_timestamp(secs: i64, nsecs: u32) -> NaiveDateTime {
116 let datetime = NaiveDateTime::from_timestamp_opt(secs, nsecs);
117 datetime.expect("invalid or out-of-range datetime")
118 }
119
120 /// Makes a new `NaiveDateTime` corresponding to a UTC date and time,
121 /// from the number of non-leap seconds
122 /// since the midnight UTC on January 1, 1970 (aka "UNIX timestamp")
123 /// and the number of nanoseconds since the last whole non-leap second.
124 ///
125 /// The nanosecond part can exceed 1,000,000,000
126 /// in order to represent the [leap second](./struct.NaiveTime.html#leap-second-handling).
127 /// (The true "UNIX timestamp" cannot represent a leap second unambiguously.)
128 ///
129 /// Returns `None` on the out-of-range number of seconds and/or invalid nanosecond.
130 ///
131 /// # Example
132 ///
133 /// ~~~~
134 /// use chrono::{NaiveDateTime, NaiveDate};
135 /// use std::i64;
136 ///
137 /// let from_timestamp_opt = NaiveDateTime::from_timestamp_opt;
138 ///
139 /// assert!(from_timestamp_opt(0, 0).is_some());
140 /// assert!(from_timestamp_opt(0, 999_999_999).is_some());
141 /// assert!(from_timestamp_opt(0, 1_500_000_000).is_some()); // leap second
142 /// assert!(from_timestamp_opt(0, 2_000_000_000).is_none());
143 /// assert!(from_timestamp_opt(i64::MAX, 0).is_none());
144 /// ~~~~
145 #[inline]
from_timestamp_opt(secs: i64, nsecs: u32) -> Option<NaiveDateTime>146 pub fn from_timestamp_opt(secs: i64, nsecs: u32) -> Option<NaiveDateTime> {
147 let (days, secs) = div_mod_floor(secs, 86_400);
148 let date = days
149 .to_i32()
150 .and_then(|days| days.checked_add(719_163))
151 .and_then(NaiveDate::from_num_days_from_ce_opt);
152 let time = NaiveTime::from_num_seconds_from_midnight_opt(secs as u32, nsecs);
153 match (date, time) {
154 (Some(date), Some(time)) => Some(NaiveDateTime { date: date, time: time }),
155 (_, _) => None,
156 }
157 }
158
159 /// Parses a string with the specified format string and returns a new `NaiveDateTime`.
160 /// See the [`format::strftime` module](../format/strftime/index.html)
161 /// on the supported escape sequences.
162 ///
163 /// # Example
164 ///
165 /// ~~~~
166 /// use chrono::{NaiveDateTime, NaiveDate};
167 ///
168 /// let parse_from_str = NaiveDateTime::parse_from_str;
169 ///
170 /// assert_eq!(parse_from_str("2015-09-05 23:56:04", "%Y-%m-%d %H:%M:%S"),
171 /// Ok(NaiveDate::from_ymd(2015, 9, 5).and_hms(23, 56, 4)));
172 /// assert_eq!(parse_from_str("5sep2015pm012345.6789", "%d%b%Y%p%I%M%S%.f"),
173 /// Ok(NaiveDate::from_ymd(2015, 9, 5).and_hms_micro(13, 23, 45, 678_900)));
174 /// ~~~~
175 ///
176 /// Offset is ignored for the purpose of parsing.
177 ///
178 /// ~~~~
179 /// # use chrono::{NaiveDateTime, NaiveDate};
180 /// # let parse_from_str = NaiveDateTime::parse_from_str;
181 /// assert_eq!(parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
182 /// Ok(NaiveDate::from_ymd(2014, 5, 17).and_hms(12, 34, 56)));
183 /// ~~~~
184 ///
185 /// [Leap seconds](./struct.NaiveTime.html#leap-second-handling) are correctly handled by
186 /// treating any time of the form `hh:mm:60` as a leap second.
187 /// (This equally applies to the formatting, so the round trip is possible.)
188 ///
189 /// ~~~~
190 /// # use chrono::{NaiveDateTime, NaiveDate};
191 /// # let parse_from_str = NaiveDateTime::parse_from_str;
192 /// assert_eq!(parse_from_str("2015-07-01 08:59:60.123", "%Y-%m-%d %H:%M:%S%.f"),
193 /// Ok(NaiveDate::from_ymd(2015, 7, 1).and_hms_milli(8, 59, 59, 1_123)));
194 /// ~~~~
195 ///
196 /// Missing seconds are assumed to be zero,
197 /// but out-of-bound times or insufficient fields are errors otherwise.
198 ///
199 /// ~~~~
200 /// # use chrono::{NaiveDateTime, NaiveDate};
201 /// # let parse_from_str = NaiveDateTime::parse_from_str;
202 /// assert_eq!(parse_from_str("94/9/4 7:15", "%y/%m/%d %H:%M"),
203 /// Ok(NaiveDate::from_ymd(1994, 9, 4).and_hms(7, 15, 0)));
204 ///
205 /// assert!(parse_from_str("04m33s", "%Mm%Ss").is_err());
206 /// assert!(parse_from_str("94/9/4 12", "%y/%m/%d %H").is_err());
207 /// assert!(parse_from_str("94/9/4 17:60", "%y/%m/%d %H:%M").is_err());
208 /// assert!(parse_from_str("94/9/4 24:00:00", "%y/%m/%d %H:%M:%S").is_err());
209 /// ~~~~
210 ///
211 /// All parsed fields should be consistent to each other, otherwise it's an error.
212 ///
213 /// ~~~~
214 /// # use chrono::NaiveDateTime;
215 /// # let parse_from_str = NaiveDateTime::parse_from_str;
216 /// let fmt = "%Y-%m-%d %H:%M:%S = UNIX timestamp %s";
217 /// assert!(parse_from_str("2001-09-09 01:46:39 = UNIX timestamp 999999999", fmt).is_ok());
218 /// assert!(parse_from_str("1970-01-01 00:00:00 = UNIX timestamp 1", fmt).is_err());
219 /// ~~~~
parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveDateTime>220 pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveDateTime> {
221 let mut parsed = Parsed::new();
222 parse(&mut parsed, s, StrftimeItems::new(fmt))?;
223 parsed.to_naive_datetime_with_offset(0) // no offset adjustment
224 }
225
226 /// Retrieves a date component.
227 ///
228 /// # Example
229 ///
230 /// ~~~~
231 /// use chrono::NaiveDate;
232 ///
233 /// let dt = NaiveDate::from_ymd(2016, 7, 8).and_hms(9, 10, 11);
234 /// assert_eq!(dt.date(), NaiveDate::from_ymd(2016, 7, 8));
235 /// ~~~~
236 #[inline]
date(&self) -> NaiveDate237 pub fn date(&self) -> NaiveDate {
238 self.date
239 }
240
241 /// Retrieves a time component.
242 ///
243 /// # Example
244 ///
245 /// ~~~~
246 /// use chrono::{NaiveDate, NaiveTime};
247 ///
248 /// let dt = NaiveDate::from_ymd(2016, 7, 8).and_hms(9, 10, 11);
249 /// assert_eq!(dt.time(), NaiveTime::from_hms(9, 10, 11));
250 /// ~~~~
251 #[inline]
time(&self) -> NaiveTime252 pub fn time(&self) -> NaiveTime {
253 self.time
254 }
255
256 /// Returns the number of non-leap seconds since the midnight on January 1, 1970.
257 ///
258 /// Note that this does *not* account for the timezone!
259 /// The true "UNIX timestamp" would count seconds since the midnight *UTC* on the epoch.
260 ///
261 /// # Example
262 ///
263 /// ~~~~
264 /// use chrono::NaiveDate;
265 ///
266 /// let dt = NaiveDate::from_ymd(1970, 1, 1).and_hms_milli(0, 0, 1, 980);
267 /// assert_eq!(dt.timestamp(), 1);
268 ///
269 /// let dt = NaiveDate::from_ymd(2001, 9, 9).and_hms(1, 46, 40);
270 /// assert_eq!(dt.timestamp(), 1_000_000_000);
271 ///
272 /// let dt = NaiveDate::from_ymd(1969, 12, 31).and_hms(23, 59, 59);
273 /// assert_eq!(dt.timestamp(), -1);
274 ///
275 /// let dt = NaiveDate::from_ymd(-1, 1, 1).and_hms(0, 0, 0);
276 /// assert_eq!(dt.timestamp(), -62198755200);
277 /// ~~~~
278 #[inline]
timestamp(&self) -> i64279 pub fn timestamp(&self) -> i64 {
280 const UNIX_EPOCH_DAY: i64 = 719_163;
281 let gregorian_day = i64::from(self.date.num_days_from_ce());
282 let seconds_from_midnight = i64::from(self.time.num_seconds_from_midnight());
283 (gregorian_day - UNIX_EPOCH_DAY) * 86_400 + seconds_from_midnight
284 }
285
286 /// Returns the number of non-leap *milliseconds* since midnight on January 1, 1970.
287 ///
288 /// Note that this does *not* account for the timezone!
289 /// The true "UNIX timestamp" would count seconds since the midnight *UTC* on the epoch.
290 ///
291 /// Note also that this does reduce the number of years that can be
292 /// represented from ~584 Billion to ~584 Million. (If this is a problem,
293 /// please file an issue to let me know what domain needs millisecond
294 /// precision over billions of years, I'm curious.)
295 ///
296 /// # Example
297 ///
298 /// ~~~~
299 /// use chrono::NaiveDate;
300 ///
301 /// let dt = NaiveDate::from_ymd(1970, 1, 1).and_hms_milli(0, 0, 1, 444);
302 /// assert_eq!(dt.timestamp_millis(), 1_444);
303 ///
304 /// let dt = NaiveDate::from_ymd(2001, 9, 9).and_hms_milli(1, 46, 40, 555);
305 /// assert_eq!(dt.timestamp_millis(), 1_000_000_000_555);
306 ///
307 /// let dt = NaiveDate::from_ymd(1969, 12, 31).and_hms_milli(23, 59, 59, 100);
308 /// assert_eq!(dt.timestamp_millis(), -900);
309 /// ~~~~
310 #[inline]
timestamp_millis(&self) -> i64311 pub fn timestamp_millis(&self) -> i64 {
312 let as_ms = self.timestamp() * 1000;
313 as_ms + i64::from(self.timestamp_subsec_millis())
314 }
315
316 /// Returns the number of non-leap *nanoseconds* since midnight on January 1, 1970.
317 ///
318 /// Note that this does *not* account for the timezone!
319 /// The true "UNIX timestamp" would count seconds since the midnight *UTC* on the epoch.
320 ///
321 /// # Panics
322 ///
323 /// Note also that this does reduce the number of years that can be
324 /// represented from ~584 Billion to ~584 years. The dates that can be
325 /// represented as nanoseconds are between 1677-09-21T00:12:44.0 and
326 /// 2262-04-11T23:47:16.854775804.
327 ///
328 /// (If this is a problem, please file an issue to let me know what domain
329 /// needs nanosecond precision over millennia, I'm curious.)
330 ///
331 /// # Example
332 ///
333 /// ~~~~
334 /// use chrono::{NaiveDate, NaiveDateTime};
335 ///
336 /// let dt = NaiveDate::from_ymd(1970, 1, 1).and_hms_nano(0, 0, 1, 444);
337 /// assert_eq!(dt.timestamp_nanos(), 1_000_000_444);
338 ///
339 /// let dt = NaiveDate::from_ymd(2001, 9, 9).and_hms_nano(1, 46, 40, 555);
340 ///
341 /// const A_BILLION: i64 = 1_000_000_000;
342 /// let nanos = dt.timestamp_nanos();
343 /// assert_eq!(nanos, 1_000_000_000_000_000_555);
344 /// assert_eq!(
345 /// dt,
346 /// NaiveDateTime::from_timestamp(nanos / A_BILLION, (nanos % A_BILLION) as u32)
347 /// );
348 /// ~~~~
349 #[inline]
timestamp_nanos(&self) -> i64350 pub fn timestamp_nanos(&self) -> i64 {
351 let as_ns = self.timestamp() * 1_000_000_000;
352 as_ns + i64::from(self.timestamp_subsec_nanos())
353 }
354
355 /// Returns the number of milliseconds since the last whole non-leap second.
356 ///
357 /// The return value ranges from 0 to 999,
358 /// or for [leap seconds](./struct.NaiveTime.html#leap-second-handling), to 1,999.
359 ///
360 /// # Example
361 ///
362 /// ~~~~
363 /// use chrono::NaiveDate;
364 ///
365 /// let dt = NaiveDate::from_ymd(2016, 7, 8).and_hms_nano(9, 10, 11, 123_456_789);
366 /// assert_eq!(dt.timestamp_subsec_millis(), 123);
367 ///
368 /// let dt = NaiveDate::from_ymd(2015, 7, 1).and_hms_nano(8, 59, 59, 1_234_567_890);
369 /// assert_eq!(dt.timestamp_subsec_millis(), 1_234);
370 /// ~~~~
371 #[inline]
timestamp_subsec_millis(&self) -> u32372 pub fn timestamp_subsec_millis(&self) -> u32 {
373 self.timestamp_subsec_nanos() / 1_000_000
374 }
375
376 /// Returns the number of microseconds since the last whole non-leap second.
377 ///
378 /// The return value ranges from 0 to 999,999,
379 /// or for [leap seconds](./struct.NaiveTime.html#leap-second-handling), to 1,999,999.
380 ///
381 /// # Example
382 ///
383 /// ~~~~
384 /// use chrono::NaiveDate;
385 ///
386 /// let dt = NaiveDate::from_ymd(2016, 7, 8).and_hms_nano(9, 10, 11, 123_456_789);
387 /// assert_eq!(dt.timestamp_subsec_micros(), 123_456);
388 ///
389 /// let dt = NaiveDate::from_ymd(2015, 7, 1).and_hms_nano(8, 59, 59, 1_234_567_890);
390 /// assert_eq!(dt.timestamp_subsec_micros(), 1_234_567);
391 /// ~~~~
392 #[inline]
timestamp_subsec_micros(&self) -> u32393 pub fn timestamp_subsec_micros(&self) -> u32 {
394 self.timestamp_subsec_nanos() / 1_000
395 }
396
397 /// Returns the number of nanoseconds since the last whole non-leap second.
398 ///
399 /// The return value ranges from 0 to 999,999,999,
400 /// or for [leap seconds](./struct.NaiveTime.html#leap-second-handling), to 1,999,999,999.
401 ///
402 /// # Example
403 ///
404 /// ~~~~
405 /// use chrono::NaiveDate;
406 ///
407 /// let dt = NaiveDate::from_ymd(2016, 7, 8).and_hms_nano(9, 10, 11, 123_456_789);
408 /// assert_eq!(dt.timestamp_subsec_nanos(), 123_456_789);
409 ///
410 /// let dt = NaiveDate::from_ymd(2015, 7, 1).and_hms_nano(8, 59, 59, 1_234_567_890);
411 /// assert_eq!(dt.timestamp_subsec_nanos(), 1_234_567_890);
412 /// ~~~~
413 #[inline]
timestamp_subsec_nanos(&self) -> u32414 pub fn timestamp_subsec_nanos(&self) -> u32 {
415 self.time.nanosecond()
416 }
417
418 /// Adds given `Duration` to the current date and time.
419 ///
420 /// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
421 /// the addition assumes that **there is no leap second ever**,
422 /// except when the `NaiveDateTime` itself represents a leap second
423 /// in which case the assumption becomes that **there is exactly a single leap second ever**.
424 ///
425 /// Returns `None` when it will result in overflow.
426 ///
427 /// # Example
428 ///
429 /// ~~~~
430 /// # extern crate chrono; extern crate time; fn main() {
431 /// use chrono::NaiveDate;
432 /// use time::Duration;
433 ///
434 /// let from_ymd = NaiveDate::from_ymd;
435 ///
436 /// let d = from_ymd(2016, 7, 8);
437 /// let hms = |h, m, s| d.and_hms(h, m, s);
438 /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::zero()),
439 /// Some(hms(3, 5, 7)));
440 /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::seconds(1)),
441 /// Some(hms(3, 5, 8)));
442 /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::seconds(-1)),
443 /// Some(hms(3, 5, 6)));
444 /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::seconds(3600 + 60)),
445 /// Some(hms(4, 6, 7)));
446 /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::seconds(86_400)),
447 /// Some(from_ymd(2016, 7, 9).and_hms(3, 5, 7)));
448 ///
449 /// let hmsm = |h, m, s, milli| d.and_hms_milli(h, m, s, milli);
450 /// assert_eq!(hmsm(3, 5, 7, 980).checked_add_signed(Duration::milliseconds(450)),
451 /// Some(hmsm(3, 5, 8, 430)));
452 /// # }
453 /// ~~~~
454 ///
455 /// Overflow returns `None`.
456 ///
457 /// ~~~~
458 /// # extern crate chrono; extern crate time; fn main() {
459 /// # use chrono::NaiveDate;
460 /// # use time::Duration;
461 /// # let hms = |h, m, s| NaiveDate::from_ymd(2016, 7, 8).and_hms(h, m, s);
462 /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::days(1_000_000_000)), None);
463 /// # }
464 /// ~~~~
465 ///
466 /// Leap seconds are handled,
467 /// but the addition assumes that it is the only leap second happened.
468 ///
469 /// ~~~~
470 /// # extern crate chrono; extern crate time; fn main() {
471 /// # use chrono::NaiveDate;
472 /// # use time::Duration;
473 /// # let from_ymd = NaiveDate::from_ymd;
474 /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli(h, m, s, milli);
475 /// let leap = hmsm(3, 5, 59, 1_300);
476 /// assert_eq!(leap.checked_add_signed(Duration::zero()),
477 /// Some(hmsm(3, 5, 59, 1_300)));
478 /// assert_eq!(leap.checked_add_signed(Duration::milliseconds(-500)),
479 /// Some(hmsm(3, 5, 59, 800)));
480 /// assert_eq!(leap.checked_add_signed(Duration::milliseconds(500)),
481 /// Some(hmsm(3, 5, 59, 1_800)));
482 /// assert_eq!(leap.checked_add_signed(Duration::milliseconds(800)),
483 /// Some(hmsm(3, 6, 0, 100)));
484 /// assert_eq!(leap.checked_add_signed(Duration::seconds(10)),
485 /// Some(hmsm(3, 6, 9, 300)));
486 /// assert_eq!(leap.checked_add_signed(Duration::seconds(-10)),
487 /// Some(hmsm(3, 5, 50, 300)));
488 /// assert_eq!(leap.checked_add_signed(Duration::days(1)),
489 /// Some(from_ymd(2016, 7, 9).and_hms_milli(3, 5, 59, 300)));
490 /// # }
491 /// ~~~~
checked_add_signed(self, rhs: OldDuration) -> Option<NaiveDateTime>492 pub fn checked_add_signed(self, rhs: OldDuration) -> Option<NaiveDateTime> {
493 let (time, rhs) = self.time.overflowing_add_signed(rhs);
494
495 // early checking to avoid overflow in OldDuration::seconds
496 if rhs <= (-1 << MAX_SECS_BITS) || rhs >= (1 << MAX_SECS_BITS) {
497 return None;
498 }
499
500 let date = try_opt!(self.date.checked_add_signed(OldDuration::seconds(rhs)));
501 Some(NaiveDateTime { date: date, time: time })
502 }
503
504 /// Subtracts given `Duration` from the current date and time.
505 ///
506 /// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
507 /// the subtraction assumes that **there is no leap second ever**,
508 /// except when the `NaiveDateTime` itself represents a leap second
509 /// in which case the assumption becomes that **there is exactly a single leap second ever**.
510 ///
511 /// Returns `None` when it will result in overflow.
512 ///
513 /// # Example
514 ///
515 /// ~~~~
516 /// # extern crate chrono; extern crate time; fn main() {
517 /// use chrono::NaiveDate;
518 /// use time::Duration;
519 ///
520 /// let from_ymd = NaiveDate::from_ymd;
521 ///
522 /// let d = from_ymd(2016, 7, 8);
523 /// let hms = |h, m, s| d.and_hms(h, m, s);
524 /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::zero()),
525 /// Some(hms(3, 5, 7)));
526 /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::seconds(1)),
527 /// Some(hms(3, 5, 6)));
528 /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::seconds(-1)),
529 /// Some(hms(3, 5, 8)));
530 /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::seconds(3600 + 60)),
531 /// Some(hms(2, 4, 7)));
532 /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::seconds(86_400)),
533 /// Some(from_ymd(2016, 7, 7).and_hms(3, 5, 7)));
534 ///
535 /// let hmsm = |h, m, s, milli| d.and_hms_milli(h, m, s, milli);
536 /// assert_eq!(hmsm(3, 5, 7, 450).checked_sub_signed(Duration::milliseconds(670)),
537 /// Some(hmsm(3, 5, 6, 780)));
538 /// # }
539 /// ~~~~
540 ///
541 /// Overflow returns `None`.
542 ///
543 /// ~~~~
544 /// # extern crate chrono; extern crate time; fn main() {
545 /// # use chrono::NaiveDate;
546 /// # use time::Duration;
547 /// # let hms = |h, m, s| NaiveDate::from_ymd(2016, 7, 8).and_hms(h, m, s);
548 /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::days(1_000_000_000)), None);
549 /// # }
550 /// ~~~~
551 ///
552 /// Leap seconds are handled,
553 /// but the subtraction assumes that it is the only leap second happened.
554 ///
555 /// ~~~~
556 /// # extern crate chrono; extern crate time; fn main() {
557 /// # use chrono::NaiveDate;
558 /// # use time::Duration;
559 /// # let from_ymd = NaiveDate::from_ymd;
560 /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli(h, m, s, milli);
561 /// let leap = hmsm(3, 5, 59, 1_300);
562 /// assert_eq!(leap.checked_sub_signed(Duration::zero()),
563 /// Some(hmsm(3, 5, 59, 1_300)));
564 /// assert_eq!(leap.checked_sub_signed(Duration::milliseconds(200)),
565 /// Some(hmsm(3, 5, 59, 1_100)));
566 /// assert_eq!(leap.checked_sub_signed(Duration::milliseconds(500)),
567 /// Some(hmsm(3, 5, 59, 800)));
568 /// assert_eq!(leap.checked_sub_signed(Duration::seconds(60)),
569 /// Some(hmsm(3, 5, 0, 300)));
570 /// assert_eq!(leap.checked_sub_signed(Duration::days(1)),
571 /// Some(from_ymd(2016, 7, 7).and_hms_milli(3, 6, 0, 300)));
572 /// # }
573 /// ~~~~
checked_sub_signed(self, rhs: OldDuration) -> Option<NaiveDateTime>574 pub fn checked_sub_signed(self, rhs: OldDuration) -> Option<NaiveDateTime> {
575 let (time, rhs) = self.time.overflowing_sub_signed(rhs);
576
577 // early checking to avoid overflow in OldDuration::seconds
578 if rhs <= (-1 << MAX_SECS_BITS) || rhs >= (1 << MAX_SECS_BITS) {
579 return None;
580 }
581
582 let date = try_opt!(self.date.checked_sub_signed(OldDuration::seconds(rhs)));
583 Some(NaiveDateTime { date: date, time: time })
584 }
585
586 /// Subtracts another `NaiveDateTime` from the current date and time.
587 /// This does not overflow or underflow at all.
588 ///
589 /// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
590 /// the subtraction assumes that **there is no leap second ever**,
591 /// except when any of the `NaiveDateTime`s themselves represents a leap second
592 /// in which case the assumption becomes that
593 /// **there are exactly one (or two) leap second(s) ever**.
594 ///
595 /// # Example
596 ///
597 /// ~~~~
598 /// # extern crate chrono; extern crate time; fn main() {
599 /// use chrono::NaiveDate;
600 /// use time::Duration;
601 ///
602 /// let from_ymd = NaiveDate::from_ymd;
603 ///
604 /// let d = from_ymd(2016, 7, 8);
605 /// assert_eq!(d.and_hms(3, 5, 7).signed_duration_since(d.and_hms(2, 4, 6)),
606 /// Duration::seconds(3600 + 60 + 1));
607 ///
608 /// // July 8 is 190th day in the year 2016
609 /// let d0 = from_ymd(2016, 1, 1);
610 /// assert_eq!(d.and_hms_milli(0, 7, 6, 500).signed_duration_since(d0.and_hms(0, 0, 0)),
611 /// Duration::seconds(189 * 86_400 + 7 * 60 + 6) + Duration::milliseconds(500));
612 /// # }
613 /// ~~~~
614 ///
615 /// Leap seconds are handled, but the subtraction assumes that
616 /// there were no other leap seconds happened.
617 ///
618 /// ~~~~
619 /// # extern crate chrono; extern crate time; fn main() {
620 /// # use chrono::NaiveDate;
621 /// # use time::Duration;
622 /// # let from_ymd = NaiveDate::from_ymd;
623 /// let leap = from_ymd(2015, 6, 30).and_hms_milli(23, 59, 59, 1_500);
624 /// assert_eq!(leap.signed_duration_since(from_ymd(2015, 6, 30).and_hms(23, 0, 0)),
625 /// Duration::seconds(3600) + Duration::milliseconds(500));
626 /// assert_eq!(from_ymd(2015, 7, 1).and_hms(1, 0, 0).signed_duration_since(leap),
627 /// Duration::seconds(3600) - Duration::milliseconds(500));
628 /// # }
629 /// ~~~~
signed_duration_since(self, rhs: NaiveDateTime) -> OldDuration630 pub fn signed_duration_since(self, rhs: NaiveDateTime) -> OldDuration {
631 self.date.signed_duration_since(rhs.date) + self.time.signed_duration_since(rhs.time)
632 }
633
634 /// Formats the combined date and time with the specified formatting items.
635 /// Otherwise it is the same as the ordinary [`format`](#method.format) method.
636 ///
637 /// The `Iterator` of items should be `Clone`able,
638 /// since the resulting `DelayedFormat` value may be formatted multiple times.
639 ///
640 /// # Example
641 ///
642 /// ~~~~
643 /// use chrono::NaiveDate;
644 /// use chrono::format::strftime::StrftimeItems;
645 ///
646 /// let fmt = StrftimeItems::new("%Y-%m-%d %H:%M:%S");
647 /// let dt = NaiveDate::from_ymd(2015, 9, 5).and_hms(23, 56, 4);
648 /// assert_eq!(dt.format_with_items(fmt.clone()).to_string(), "2015-09-05 23:56:04");
649 /// assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2015-09-05 23:56:04");
650 /// ~~~~
651 ///
652 /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
653 ///
654 /// ~~~~
655 /// # use chrono::NaiveDate;
656 /// # use chrono::format::strftime::StrftimeItems;
657 /// # let fmt = StrftimeItems::new("%Y-%m-%d %H:%M:%S").clone();
658 /// # let dt = NaiveDate::from_ymd(2015, 9, 5).and_hms(23, 56, 4);
659 /// assert_eq!(format!("{}", dt.format_with_items(fmt)), "2015-09-05 23:56:04");
660 /// ~~~~
661 #[cfg(any(feature = "alloc", feature = "std", test))]
662 #[inline]
format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat<I> where I: Iterator<Item = B> + Clone, B: Borrow<Item<'a>>,663 pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat<I>
664 where
665 I: Iterator<Item = B> + Clone,
666 B: Borrow<Item<'a>>,
667 {
668 DelayedFormat::new(Some(self.date), Some(self.time), items)
669 }
670
671 /// Formats the combined date and time with the specified format string.
672 /// See the [`format::strftime` module](../format/strftime/index.html)
673 /// on the supported escape sequences.
674 ///
675 /// This returns a `DelayedFormat`,
676 /// which gets converted to a string only when actual formatting happens.
677 /// You may use the `to_string` method to get a `String`,
678 /// or just feed it into `print!` and other formatting macros.
679 /// (In this way it avoids the redundant memory allocation.)
680 ///
681 /// A wrong format string does *not* issue an error immediately.
682 /// Rather, converting or formatting the `DelayedFormat` fails.
683 /// You are recommended to immediately use `DelayedFormat` for this reason.
684 ///
685 /// # Example
686 ///
687 /// ~~~~
688 /// use chrono::NaiveDate;
689 ///
690 /// let dt = NaiveDate::from_ymd(2015, 9, 5).and_hms(23, 56, 4);
691 /// assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2015-09-05 23:56:04");
692 /// assert_eq!(dt.format("around %l %p on %b %-d").to_string(), "around 11 PM on Sep 5");
693 /// ~~~~
694 ///
695 /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
696 ///
697 /// ~~~~
698 /// # use chrono::NaiveDate;
699 /// # let dt = NaiveDate::from_ymd(2015, 9, 5).and_hms(23, 56, 4);
700 /// assert_eq!(format!("{}", dt.format("%Y-%m-%d %H:%M:%S")), "2015-09-05 23:56:04");
701 /// assert_eq!(format!("{}", dt.format("around %l %p on %b %-d")), "around 11 PM on Sep 5");
702 /// ~~~~
703 #[cfg(any(feature = "alloc", feature = "std", test))]
704 #[inline]
format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>>705 pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
706 self.format_with_items(StrftimeItems::new(fmt))
707 }
708 }
709
710 impl Datelike for NaiveDateTime {
711 /// Returns the year number in the [calendar date](./index.html#calendar-date).
712 ///
713 /// See also the [`NaiveDate::year`](./struct.NaiveDate.html#method.year) method.
714 ///
715 /// # Example
716 ///
717 /// ~~~~
718 /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
719 ///
720 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
721 /// assert_eq!(dt.year(), 2015);
722 /// ~~~~
723 #[inline]
year(&self) -> i32724 fn year(&self) -> i32 {
725 self.date.year()
726 }
727
728 /// Returns the month number starting from 1.
729 ///
730 /// The return value ranges from 1 to 12.
731 ///
732 /// See also the [`NaiveDate::month`](./struct.NaiveDate.html#method.month) method.
733 ///
734 /// # Example
735 ///
736 /// ~~~~
737 /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
738 ///
739 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
740 /// assert_eq!(dt.month(), 9);
741 /// ~~~~
742 #[inline]
month(&self) -> u32743 fn month(&self) -> u32 {
744 self.date.month()
745 }
746
747 /// Returns the month number starting from 0.
748 ///
749 /// The return value ranges from 0 to 11.
750 ///
751 /// See also the [`NaiveDate::month0`](./struct.NaiveDate.html#method.month0) method.
752 ///
753 /// # Example
754 ///
755 /// ~~~~
756 /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
757 ///
758 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
759 /// assert_eq!(dt.month0(), 8);
760 /// ~~~~
761 #[inline]
month0(&self) -> u32762 fn month0(&self) -> u32 {
763 self.date.month0()
764 }
765
766 /// Returns the day of month starting from 1.
767 ///
768 /// The return value ranges from 1 to 31. (The last day of month differs by months.)
769 ///
770 /// See also the [`NaiveDate::day`](./struct.NaiveDate.html#method.day) method.
771 ///
772 /// # Example
773 ///
774 /// ~~~~
775 /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
776 ///
777 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
778 /// assert_eq!(dt.day(), 25);
779 /// ~~~~
780 #[inline]
day(&self) -> u32781 fn day(&self) -> u32 {
782 self.date.day()
783 }
784
785 /// Returns the day of month starting from 0.
786 ///
787 /// The return value ranges from 0 to 30. (The last day of month differs by months.)
788 ///
789 /// See also the [`NaiveDate::day0`](./struct.NaiveDate.html#method.day0) method.
790 ///
791 /// # Example
792 ///
793 /// ~~~~
794 /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
795 ///
796 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
797 /// assert_eq!(dt.day0(), 24);
798 /// ~~~~
799 #[inline]
day0(&self) -> u32800 fn day0(&self) -> u32 {
801 self.date.day0()
802 }
803
804 /// Returns the day of year starting from 1.
805 ///
806 /// The return value ranges from 1 to 366. (The last day of year differs by years.)
807 ///
808 /// See also the [`NaiveDate::ordinal`](./struct.NaiveDate.html#method.ordinal) method.
809 ///
810 /// # Example
811 ///
812 /// ~~~~
813 /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
814 ///
815 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
816 /// assert_eq!(dt.ordinal(), 268);
817 /// ~~~~
818 #[inline]
ordinal(&self) -> u32819 fn ordinal(&self) -> u32 {
820 self.date.ordinal()
821 }
822
823 /// Returns the day of year starting from 0.
824 ///
825 /// The return value ranges from 0 to 365. (The last day of year differs by years.)
826 ///
827 /// See also the [`NaiveDate::ordinal0`](./struct.NaiveDate.html#method.ordinal0) method.
828 ///
829 /// # Example
830 ///
831 /// ~~~~
832 /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
833 ///
834 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
835 /// assert_eq!(dt.ordinal0(), 267);
836 /// ~~~~
837 #[inline]
ordinal0(&self) -> u32838 fn ordinal0(&self) -> u32 {
839 self.date.ordinal0()
840 }
841
842 /// Returns the day of week.
843 ///
844 /// See also the [`NaiveDate::weekday`](./struct.NaiveDate.html#method.weekday) method.
845 ///
846 /// # Example
847 ///
848 /// ~~~~
849 /// use chrono::{NaiveDate, NaiveDateTime, Datelike, Weekday};
850 ///
851 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
852 /// assert_eq!(dt.weekday(), Weekday::Fri);
853 /// ~~~~
854 #[inline]
weekday(&self) -> Weekday855 fn weekday(&self) -> Weekday {
856 self.date.weekday()
857 }
858
859 #[inline]
iso_week(&self) -> IsoWeek860 fn iso_week(&self) -> IsoWeek {
861 self.date.iso_week()
862 }
863
864 /// Makes a new `NaiveDateTime` with the year number changed.
865 ///
866 /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
867 ///
868 /// See also the
869 /// [`NaiveDate::with_year`](./struct.NaiveDate.html#method.with_year) method.
870 ///
871 /// # Example
872 ///
873 /// ~~~~
874 /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
875 ///
876 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
877 /// assert_eq!(dt.with_year(2016), Some(NaiveDate::from_ymd(2016, 9, 25).and_hms(12, 34, 56)));
878 /// assert_eq!(dt.with_year(-308), Some(NaiveDate::from_ymd(-308, 9, 25).and_hms(12, 34, 56)));
879 /// ~~~~
880 #[inline]
with_year(&self, year: i32) -> Option<NaiveDateTime>881 fn with_year(&self, year: i32) -> Option<NaiveDateTime> {
882 self.date.with_year(year).map(|d| NaiveDateTime { date: d, ..*self })
883 }
884
885 /// Makes a new `NaiveDateTime` with the month number (starting from 1) changed.
886 ///
887 /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
888 ///
889 /// See also the
890 /// [`NaiveDate::with_month`](./struct.NaiveDate.html#method.with_month) method.
891 ///
892 /// # Example
893 ///
894 /// ~~~~
895 /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
896 ///
897 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 30).and_hms(12, 34, 56);
898 /// assert_eq!(dt.with_month(10), Some(NaiveDate::from_ymd(2015, 10, 30).and_hms(12, 34, 56)));
899 /// assert_eq!(dt.with_month(13), None); // no month 13
900 /// assert_eq!(dt.with_month(2), None); // no February 30
901 /// ~~~~
902 #[inline]
with_month(&self, month: u32) -> Option<NaiveDateTime>903 fn with_month(&self, month: u32) -> Option<NaiveDateTime> {
904 self.date.with_month(month).map(|d| NaiveDateTime { date: d, ..*self })
905 }
906
907 /// Makes a new `NaiveDateTime` with the month number (starting from 0) changed.
908 ///
909 /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
910 ///
911 /// See also the
912 /// [`NaiveDate::with_month0`](./struct.NaiveDate.html#method.with_month0) method.
913 ///
914 /// # Example
915 ///
916 /// ~~~~
917 /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
918 ///
919 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 30).and_hms(12, 34, 56);
920 /// assert_eq!(dt.with_month0(9), Some(NaiveDate::from_ymd(2015, 10, 30).and_hms(12, 34, 56)));
921 /// assert_eq!(dt.with_month0(12), None); // no month 13
922 /// assert_eq!(dt.with_month0(1), None); // no February 30
923 /// ~~~~
924 #[inline]
with_month0(&self, month0: u32) -> Option<NaiveDateTime>925 fn with_month0(&self, month0: u32) -> Option<NaiveDateTime> {
926 self.date.with_month0(month0).map(|d| NaiveDateTime { date: d, ..*self })
927 }
928
929 /// Makes a new `NaiveDateTime` with the day of month (starting from 1) changed.
930 ///
931 /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
932 ///
933 /// See also the
934 /// [`NaiveDate::with_day`](./struct.NaiveDate.html#method.with_day) method.
935 ///
936 /// # Example
937 ///
938 /// ~~~~
939 /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
940 ///
941 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms(12, 34, 56);
942 /// assert_eq!(dt.with_day(30), Some(NaiveDate::from_ymd(2015, 9, 30).and_hms(12, 34, 56)));
943 /// assert_eq!(dt.with_day(31), None); // no September 31
944 /// ~~~~
945 #[inline]
with_day(&self, day: u32) -> Option<NaiveDateTime>946 fn with_day(&self, day: u32) -> Option<NaiveDateTime> {
947 self.date.with_day(day).map(|d| NaiveDateTime { date: d, ..*self })
948 }
949
950 /// Makes a new `NaiveDateTime` with the day of month (starting from 0) changed.
951 ///
952 /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
953 ///
954 /// See also the
955 /// [`NaiveDate::with_day0`](./struct.NaiveDate.html#method.with_day0) method.
956 ///
957 /// # Example
958 ///
959 /// ~~~~
960 /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
961 ///
962 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms(12, 34, 56);
963 /// assert_eq!(dt.with_day0(29), Some(NaiveDate::from_ymd(2015, 9, 30).and_hms(12, 34, 56)));
964 /// assert_eq!(dt.with_day0(30), None); // no September 31
965 /// ~~~~
966 #[inline]
with_day0(&self, day0: u32) -> Option<NaiveDateTime>967 fn with_day0(&self, day0: u32) -> Option<NaiveDateTime> {
968 self.date.with_day0(day0).map(|d| NaiveDateTime { date: d, ..*self })
969 }
970
971 /// Makes a new `NaiveDateTime` with the day of year (starting from 1) changed.
972 ///
973 /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
974 ///
975 /// See also the
976 /// [`NaiveDate::with_ordinal`](./struct.NaiveDate.html#method.with_ordinal) method.
977 ///
978 /// # Example
979 ///
980 /// ~~~~
981 /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
982 ///
983 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms(12, 34, 56);
984 /// assert_eq!(dt.with_ordinal(60),
985 /// Some(NaiveDate::from_ymd(2015, 3, 1).and_hms(12, 34, 56)));
986 /// assert_eq!(dt.with_ordinal(366), None); // 2015 had only 365 days
987 ///
988 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2016, 9, 8).and_hms(12, 34, 56);
989 /// assert_eq!(dt.with_ordinal(60),
990 /// Some(NaiveDate::from_ymd(2016, 2, 29).and_hms(12, 34, 56)));
991 /// assert_eq!(dt.with_ordinal(366),
992 /// Some(NaiveDate::from_ymd(2016, 12, 31).and_hms(12, 34, 56)));
993 /// ~~~~
994 #[inline]
with_ordinal(&self, ordinal: u32) -> Option<NaiveDateTime>995 fn with_ordinal(&self, ordinal: u32) -> Option<NaiveDateTime> {
996 self.date.with_ordinal(ordinal).map(|d| NaiveDateTime { date: d, ..*self })
997 }
998
999 /// Makes a new `NaiveDateTime` with the day of year (starting from 0) changed.
1000 ///
1001 /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
1002 ///
1003 /// See also the
1004 /// [`NaiveDate::with_ordinal0`](./struct.NaiveDate.html#method.with_ordinal0) method.
1005 ///
1006 /// # Example
1007 ///
1008 /// ~~~~
1009 /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
1010 ///
1011 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms(12, 34, 56);
1012 /// assert_eq!(dt.with_ordinal0(59),
1013 /// Some(NaiveDate::from_ymd(2015, 3, 1).and_hms(12, 34, 56)));
1014 /// assert_eq!(dt.with_ordinal0(365), None); // 2015 had only 365 days
1015 ///
1016 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2016, 9, 8).and_hms(12, 34, 56);
1017 /// assert_eq!(dt.with_ordinal0(59),
1018 /// Some(NaiveDate::from_ymd(2016, 2, 29).and_hms(12, 34, 56)));
1019 /// assert_eq!(dt.with_ordinal0(365),
1020 /// Some(NaiveDate::from_ymd(2016, 12, 31).and_hms(12, 34, 56)));
1021 /// ~~~~
1022 #[inline]
with_ordinal0(&self, ordinal0: u32) -> Option<NaiveDateTime>1023 fn with_ordinal0(&self, ordinal0: u32) -> Option<NaiveDateTime> {
1024 self.date.with_ordinal0(ordinal0).map(|d| NaiveDateTime { date: d, ..*self })
1025 }
1026 }
1027
1028 impl Timelike for NaiveDateTime {
1029 /// Returns the hour number from 0 to 23.
1030 ///
1031 /// See also the [`NaiveTime::hour`](./struct.NaiveTime.html#method.hour) method.
1032 ///
1033 /// # Example
1034 ///
1035 /// ~~~~
1036 /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
1037 ///
1038 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 56, 789);
1039 /// assert_eq!(dt.hour(), 12);
1040 /// ~~~~
1041 #[inline]
hour(&self) -> u321042 fn hour(&self) -> u32 {
1043 self.time.hour()
1044 }
1045
1046 /// Returns the minute number from 0 to 59.
1047 ///
1048 /// See also the [`NaiveTime::minute`](./struct.NaiveTime.html#method.minute) method.
1049 ///
1050 /// # Example
1051 ///
1052 /// ~~~~
1053 /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
1054 ///
1055 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 56, 789);
1056 /// assert_eq!(dt.minute(), 34);
1057 /// ~~~~
1058 #[inline]
minute(&self) -> u321059 fn minute(&self) -> u32 {
1060 self.time.minute()
1061 }
1062
1063 /// Returns the second number from 0 to 59.
1064 ///
1065 /// See also the [`NaiveTime::second`](./struct.NaiveTime.html#method.second) method.
1066 ///
1067 /// # Example
1068 ///
1069 /// ~~~~
1070 /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
1071 ///
1072 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 56, 789);
1073 /// assert_eq!(dt.second(), 56);
1074 /// ~~~~
1075 #[inline]
second(&self) -> u321076 fn second(&self) -> u32 {
1077 self.time.second()
1078 }
1079
1080 /// Returns the number of nanoseconds since the whole non-leap second.
1081 /// The range from 1,000,000,000 to 1,999,999,999 represents
1082 /// the [leap second](./struct.NaiveTime.html#leap-second-handling).
1083 ///
1084 /// See also the
1085 /// [`NaiveTime::nanosecond`](./struct.NaiveTime.html#method.nanosecond) method.
1086 ///
1087 /// # Example
1088 ///
1089 /// ~~~~
1090 /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
1091 ///
1092 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 56, 789);
1093 /// assert_eq!(dt.nanosecond(), 789_000_000);
1094 /// ~~~~
1095 #[inline]
nanosecond(&self) -> u321096 fn nanosecond(&self) -> u32 {
1097 self.time.nanosecond()
1098 }
1099
1100 /// Makes a new `NaiveDateTime` with the hour number changed.
1101 ///
1102 /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
1103 ///
1104 /// See also the
1105 /// [`NaiveTime::with_hour`](./struct.NaiveTime.html#method.with_hour) method.
1106 ///
1107 /// # Example
1108 ///
1109 /// ~~~~
1110 /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
1111 ///
1112 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 56, 789);
1113 /// assert_eq!(dt.with_hour(7),
1114 /// Some(NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(7, 34, 56, 789)));
1115 /// assert_eq!(dt.with_hour(24), None);
1116 /// ~~~~
1117 #[inline]
with_hour(&self, hour: u32) -> Option<NaiveDateTime>1118 fn with_hour(&self, hour: u32) -> Option<NaiveDateTime> {
1119 self.time.with_hour(hour).map(|t| NaiveDateTime { time: t, ..*self })
1120 }
1121
1122 /// Makes a new `NaiveDateTime` with the minute number changed.
1123 ///
1124 /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
1125 ///
1126 /// See also the
1127 /// [`NaiveTime::with_minute`](./struct.NaiveTime.html#method.with_minute) method.
1128 ///
1129 /// # Example
1130 ///
1131 /// ~~~~
1132 /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
1133 ///
1134 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 56, 789);
1135 /// assert_eq!(dt.with_minute(45),
1136 /// Some(NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 45, 56, 789)));
1137 /// assert_eq!(dt.with_minute(60), None);
1138 /// ~~~~
1139 #[inline]
with_minute(&self, min: u32) -> Option<NaiveDateTime>1140 fn with_minute(&self, min: u32) -> Option<NaiveDateTime> {
1141 self.time.with_minute(min).map(|t| NaiveDateTime { time: t, ..*self })
1142 }
1143
1144 /// Makes a new `NaiveDateTime` with the second number changed.
1145 ///
1146 /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
1147 /// As with the [`second`](#method.second) method,
1148 /// the input range is restricted to 0 through 59.
1149 ///
1150 /// See also the
1151 /// [`NaiveTime::with_second`](./struct.NaiveTime.html#method.with_second) method.
1152 ///
1153 /// # Example
1154 ///
1155 /// ~~~~
1156 /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
1157 ///
1158 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 56, 789);
1159 /// assert_eq!(dt.with_second(17),
1160 /// Some(NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 17, 789)));
1161 /// assert_eq!(dt.with_second(60), None);
1162 /// ~~~~
1163 #[inline]
with_second(&self, sec: u32) -> Option<NaiveDateTime>1164 fn with_second(&self, sec: u32) -> Option<NaiveDateTime> {
1165 self.time.with_second(sec).map(|t| NaiveDateTime { time: t, ..*self })
1166 }
1167
1168 /// Makes a new `NaiveDateTime` with nanoseconds since the whole non-leap second changed.
1169 ///
1170 /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
1171 /// As with the [`nanosecond`](#method.nanosecond) method,
1172 /// the input range can exceed 1,000,000,000 for leap seconds.
1173 ///
1174 /// See also the
1175 /// [`NaiveTime::with_nanosecond`](./struct.NaiveTime.html#method.with_nanosecond)
1176 /// method.
1177 ///
1178 /// # Example
1179 ///
1180 /// ~~~~
1181 /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
1182 ///
1183 /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 56, 789);
1184 /// assert_eq!(dt.with_nanosecond(333_333_333),
1185 /// Some(NaiveDate::from_ymd(2015, 9, 8).and_hms_nano(12, 34, 56, 333_333_333)));
1186 /// assert_eq!(dt.with_nanosecond(1_333_333_333), // leap second
1187 /// Some(NaiveDate::from_ymd(2015, 9, 8).and_hms_nano(12, 34, 56, 1_333_333_333)));
1188 /// assert_eq!(dt.with_nanosecond(2_000_000_000), None);
1189 /// ~~~~
1190 #[inline]
with_nanosecond(&self, nano: u32) -> Option<NaiveDateTime>1191 fn with_nanosecond(&self, nano: u32) -> Option<NaiveDateTime> {
1192 self.time.with_nanosecond(nano).map(|t| NaiveDateTime { time: t, ..*self })
1193 }
1194 }
1195
1196 /// `NaiveDateTime` can be used as a key to the hash maps (in principle).
1197 ///
1198 /// Practically this also takes account of fractional seconds, so it is not recommended.
1199 /// (For the obvious reason this also distinguishes leap seconds from non-leap seconds.)
1200 impl hash::Hash for NaiveDateTime {
hash<H: hash::Hasher>(&self, state: &mut H)1201 fn hash<H: hash::Hasher>(&self, state: &mut H) {
1202 self.date.hash(state);
1203 self.time.hash(state);
1204 }
1205 }
1206
1207 /// An addition of `Duration` to `NaiveDateTime` yields another `NaiveDateTime`.
1208 ///
1209 /// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
1210 /// the addition assumes that **there is no leap second ever**,
1211 /// except when the `NaiveDateTime` itself represents a leap second
1212 /// in which case the assumption becomes that **there is exactly a single leap second ever**.
1213 ///
1214 /// Panics on underflow or overflow.
1215 /// Use [`NaiveDateTime::checked_add_signed`](#method.checked_add_signed) to detect that.
1216 ///
1217 /// # Example
1218 ///
1219 /// ~~~~
1220 /// # extern crate chrono; extern crate time; fn main() {
1221 /// use chrono::NaiveDate;
1222 /// use time::Duration;
1223 ///
1224 /// let from_ymd = NaiveDate::from_ymd;
1225 ///
1226 /// let d = from_ymd(2016, 7, 8);
1227 /// let hms = |h, m, s| d.and_hms(h, m, s);
1228 /// assert_eq!(hms(3, 5, 7) + Duration::zero(), hms(3, 5, 7));
1229 /// assert_eq!(hms(3, 5, 7) + Duration::seconds(1), hms(3, 5, 8));
1230 /// assert_eq!(hms(3, 5, 7) + Duration::seconds(-1), hms(3, 5, 6));
1231 /// assert_eq!(hms(3, 5, 7) + Duration::seconds(3600 + 60), hms(4, 6, 7));
1232 /// assert_eq!(hms(3, 5, 7) + Duration::seconds(86_400),
1233 /// from_ymd(2016, 7, 9).and_hms(3, 5, 7));
1234 /// assert_eq!(hms(3, 5, 7) + Duration::days(365),
1235 /// from_ymd(2017, 7, 8).and_hms(3, 5, 7));
1236 ///
1237 /// let hmsm = |h, m, s, milli| d.and_hms_milli(h, m, s, milli);
1238 /// assert_eq!(hmsm(3, 5, 7, 980) + Duration::milliseconds(450), hmsm(3, 5, 8, 430));
1239 /// # }
1240 /// ~~~~
1241 ///
1242 /// Leap seconds are handled,
1243 /// but the addition assumes that it is the only leap second happened.
1244 ///
1245 /// ~~~~
1246 /// # extern crate chrono; extern crate time; fn main() {
1247 /// # use chrono::NaiveDate;
1248 /// # use time::Duration;
1249 /// # let from_ymd = NaiveDate::from_ymd;
1250 /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli(h, m, s, milli);
1251 /// let leap = hmsm(3, 5, 59, 1_300);
1252 /// assert_eq!(leap + Duration::zero(), hmsm(3, 5, 59, 1_300));
1253 /// assert_eq!(leap + Duration::milliseconds(-500), hmsm(3, 5, 59, 800));
1254 /// assert_eq!(leap + Duration::milliseconds(500), hmsm(3, 5, 59, 1_800));
1255 /// assert_eq!(leap + Duration::milliseconds(800), hmsm(3, 6, 0, 100));
1256 /// assert_eq!(leap + Duration::seconds(10), hmsm(3, 6, 9, 300));
1257 /// assert_eq!(leap + Duration::seconds(-10), hmsm(3, 5, 50, 300));
1258 /// assert_eq!(leap + Duration::days(1),
1259 /// from_ymd(2016, 7, 9).and_hms_milli(3, 5, 59, 300));
1260 /// # }
1261 /// ~~~~
1262 impl Add<OldDuration> for NaiveDateTime {
1263 type Output = NaiveDateTime;
1264
1265 #[inline]
add(self, rhs: OldDuration) -> NaiveDateTime1266 fn add(self, rhs: OldDuration) -> NaiveDateTime {
1267 self.checked_add_signed(rhs).expect("`NaiveDateTime + Duration` overflowed")
1268 }
1269 }
1270
1271 impl AddAssign<OldDuration> for NaiveDateTime {
1272 #[inline]
add_assign(&mut self, rhs: OldDuration)1273 fn add_assign(&mut self, rhs: OldDuration) {
1274 *self = self.add(rhs);
1275 }
1276 }
1277
1278 /// A subtraction of `Duration` from `NaiveDateTime` yields another `NaiveDateTime`.
1279 /// It is the same as the addition with a negated `Duration`.
1280 ///
1281 /// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
1282 /// the addition assumes that **there is no leap second ever**,
1283 /// except when the `NaiveDateTime` itself represents a leap second
1284 /// in which case the assumption becomes that **there is exactly a single leap second ever**.
1285 ///
1286 /// Panics on underflow or overflow.
1287 /// Use [`NaiveDateTime::checked_sub_signed`](#method.checked_sub_signed) to detect that.
1288 ///
1289 /// # Example
1290 ///
1291 /// ~~~~
1292 /// # extern crate chrono; extern crate time; fn main() {
1293 /// use chrono::NaiveDate;
1294 /// use time::Duration;
1295 ///
1296 /// let from_ymd = NaiveDate::from_ymd;
1297 ///
1298 /// let d = from_ymd(2016, 7, 8);
1299 /// let hms = |h, m, s| d.and_hms(h, m, s);
1300 /// assert_eq!(hms(3, 5, 7) - Duration::zero(), hms(3, 5, 7));
1301 /// assert_eq!(hms(3, 5, 7) - Duration::seconds(1), hms(3, 5, 6));
1302 /// assert_eq!(hms(3, 5, 7) - Duration::seconds(-1), hms(3, 5, 8));
1303 /// assert_eq!(hms(3, 5, 7) - Duration::seconds(3600 + 60), hms(2, 4, 7));
1304 /// assert_eq!(hms(3, 5, 7) - Duration::seconds(86_400),
1305 /// from_ymd(2016, 7, 7).and_hms(3, 5, 7));
1306 /// assert_eq!(hms(3, 5, 7) - Duration::days(365),
1307 /// from_ymd(2015, 7, 9).and_hms(3, 5, 7));
1308 ///
1309 /// let hmsm = |h, m, s, milli| d.and_hms_milli(h, m, s, milli);
1310 /// assert_eq!(hmsm(3, 5, 7, 450) - Duration::milliseconds(670), hmsm(3, 5, 6, 780));
1311 /// # }
1312 /// ~~~~
1313 ///
1314 /// Leap seconds are handled,
1315 /// but the subtraction assumes that it is the only leap second happened.
1316 ///
1317 /// ~~~~
1318 /// # extern crate chrono; extern crate time; fn main() {
1319 /// # use chrono::NaiveDate;
1320 /// # use time::Duration;
1321 /// # let from_ymd = NaiveDate::from_ymd;
1322 /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli(h, m, s, milli);
1323 /// let leap = hmsm(3, 5, 59, 1_300);
1324 /// assert_eq!(leap - Duration::zero(), hmsm(3, 5, 59, 1_300));
1325 /// assert_eq!(leap - Duration::milliseconds(200), hmsm(3, 5, 59, 1_100));
1326 /// assert_eq!(leap - Duration::milliseconds(500), hmsm(3, 5, 59, 800));
1327 /// assert_eq!(leap - Duration::seconds(60), hmsm(3, 5, 0, 300));
1328 /// assert_eq!(leap - Duration::days(1),
1329 /// from_ymd(2016, 7, 7).and_hms_milli(3, 6, 0, 300));
1330 /// # }
1331 /// ~~~~
1332 impl Sub<OldDuration> for NaiveDateTime {
1333 type Output = NaiveDateTime;
1334
1335 #[inline]
sub(self, rhs: OldDuration) -> NaiveDateTime1336 fn sub(self, rhs: OldDuration) -> NaiveDateTime {
1337 self.checked_sub_signed(rhs).expect("`NaiveDateTime - Duration` overflowed")
1338 }
1339 }
1340
1341 impl SubAssign<OldDuration> for NaiveDateTime {
1342 #[inline]
sub_assign(&mut self, rhs: OldDuration)1343 fn sub_assign(&mut self, rhs: OldDuration) {
1344 *self = self.sub(rhs);
1345 }
1346 }
1347
1348 /// Subtracts another `NaiveDateTime` from the current date and time.
1349 /// This does not overflow or underflow at all.
1350 ///
1351 /// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
1352 /// the subtraction assumes that **there is no leap second ever**,
1353 /// except when any of the `NaiveDateTime`s themselves represents a leap second
1354 /// in which case the assumption becomes that
1355 /// **there are exactly one (or two) leap second(s) ever**.
1356 ///
1357 /// The implementation is a wrapper around
1358 /// [`NaiveDateTime::signed_duration_since`](#method.signed_duration_since).
1359 ///
1360 /// # Example
1361 ///
1362 /// ~~~~
1363 /// # extern crate chrono; extern crate time; fn main() {
1364 /// use chrono::NaiveDate;
1365 /// use time::Duration;
1366 ///
1367 /// let from_ymd = NaiveDate::from_ymd;
1368 ///
1369 /// let d = from_ymd(2016, 7, 8);
1370 /// assert_eq!(d.and_hms(3, 5, 7) - d.and_hms(2, 4, 6), Duration::seconds(3600 + 60 + 1));
1371 ///
1372 /// // July 8 is 190th day in the year 2016
1373 /// let d0 = from_ymd(2016, 1, 1);
1374 /// assert_eq!(d.and_hms_milli(0, 7, 6, 500) - d0.and_hms(0, 0, 0),
1375 /// Duration::seconds(189 * 86_400 + 7 * 60 + 6) + Duration::milliseconds(500));
1376 /// # }
1377 /// ~~~~
1378 ///
1379 /// Leap seconds are handled, but the subtraction assumes that
1380 /// there were no other leap seconds happened.
1381 ///
1382 /// ~~~~
1383 /// # extern crate chrono; extern crate time; fn main() {
1384 /// # use chrono::NaiveDate;
1385 /// # use time::Duration;
1386 /// # let from_ymd = NaiveDate::from_ymd;
1387 /// let leap = from_ymd(2015, 6, 30).and_hms_milli(23, 59, 59, 1_500);
1388 /// assert_eq!(leap - from_ymd(2015, 6, 30).and_hms(23, 0, 0),
1389 /// Duration::seconds(3600) + Duration::milliseconds(500));
1390 /// assert_eq!(from_ymd(2015, 7, 1).and_hms(1, 0, 0) - leap,
1391 /// Duration::seconds(3600) - Duration::milliseconds(500));
1392 /// # }
1393 /// ~~~~
1394 impl Sub<NaiveDateTime> for NaiveDateTime {
1395 type Output = OldDuration;
1396
1397 #[inline]
sub(self, rhs: NaiveDateTime) -> OldDuration1398 fn sub(self, rhs: NaiveDateTime) -> OldDuration {
1399 self.signed_duration_since(rhs)
1400 }
1401 }
1402
1403 /// The `Debug` output of the naive date and time `dt` is the same as
1404 /// [`dt.format("%Y-%m-%dT%H:%M:%S%.f")`](../format/strftime/index.html).
1405 ///
1406 /// The string printed can be readily parsed via the `parse` method on `str`.
1407 ///
1408 /// It should be noted that, for leap seconds not on the minute boundary,
1409 /// it may print a representation not distinguishable from non-leap seconds.
1410 /// This doesn't matter in practice, since such leap seconds never happened.
1411 /// (By the time of the first leap second on 1972-06-30,
1412 /// every time zone offset around the world has standardized to the 5-minute alignment.)
1413 ///
1414 /// # Example
1415 ///
1416 /// ~~~~
1417 /// use chrono::NaiveDate;
1418 ///
1419 /// let dt = NaiveDate::from_ymd(2016, 11, 15).and_hms(7, 39, 24);
1420 /// assert_eq!(format!("{:?}", dt), "2016-11-15T07:39:24");
1421 /// ~~~~
1422 ///
1423 /// Leap seconds may also be used.
1424 ///
1425 /// ~~~~
1426 /// # use chrono::NaiveDate;
1427 /// let dt = NaiveDate::from_ymd(2015, 6, 30).and_hms_milli(23, 59, 59, 1_500);
1428 /// assert_eq!(format!("{:?}", dt), "2015-06-30T23:59:60.500");
1429 /// ~~~~
1430 impl fmt::Debug for NaiveDateTime {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1431 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1432 write!(f, "{:?}T{:?}", self.date, self.time)
1433 }
1434 }
1435
1436 /// The `Debug` output of the naive date and time `dt` is the same as
1437 /// [`dt.format("%Y-%m-%d %H:%M:%S%.f")`](../format/strftime/index.html).
1438 ///
1439 /// It should be noted that, for leap seconds not on the minute boundary,
1440 /// it may print a representation not distinguishable from non-leap seconds.
1441 /// This doesn't matter in practice, since such leap seconds never happened.
1442 /// (By the time of the first leap second on 1972-06-30,
1443 /// every time zone offset around the world has standardized to the 5-minute alignment.)
1444 ///
1445 /// # Example
1446 ///
1447 /// ~~~~
1448 /// use chrono::NaiveDate;
1449 ///
1450 /// let dt = NaiveDate::from_ymd(2016, 11, 15).and_hms(7, 39, 24);
1451 /// assert_eq!(format!("{}", dt), "2016-11-15 07:39:24");
1452 /// ~~~~
1453 ///
1454 /// Leap seconds may also be used.
1455 ///
1456 /// ~~~~
1457 /// # use chrono::NaiveDate;
1458 /// let dt = NaiveDate::from_ymd(2015, 6, 30).and_hms_milli(23, 59, 59, 1_500);
1459 /// assert_eq!(format!("{}", dt), "2015-06-30 23:59:60.500");
1460 /// ~~~~
1461 impl fmt::Display for NaiveDateTime {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1462 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1463 write!(f, "{} {}", self.date, self.time)
1464 }
1465 }
1466
1467 /// Parsing a `str` into a `NaiveDateTime` uses the same format,
1468 /// [`%Y-%m-%dT%H:%M:%S%.f`](../format/strftime/index.html), as in `Debug`.
1469 ///
1470 /// # Example
1471 ///
1472 /// ~~~~
1473 /// use chrono::{NaiveDateTime, NaiveDate};
1474 ///
1475 /// let dt = NaiveDate::from_ymd(2015, 9, 18).and_hms(23, 56, 4);
1476 /// assert_eq!("2015-09-18T23:56:04".parse::<NaiveDateTime>(), Ok(dt));
1477 ///
1478 /// let dt = NaiveDate::from_ymd(12345, 6, 7).and_hms_milli(7, 59, 59, 1_500); // leap second
1479 /// assert_eq!("+12345-6-7T7:59:60.5".parse::<NaiveDateTime>(), Ok(dt));
1480 ///
1481 /// assert!("foo".parse::<NaiveDateTime>().is_err());
1482 /// ~~~~
1483 impl str::FromStr for NaiveDateTime {
1484 type Err = ParseError;
1485
from_str(s: &str) -> ParseResult<NaiveDateTime>1486 fn from_str(s: &str) -> ParseResult<NaiveDateTime> {
1487 const ITEMS: &'static [Item<'static>] = &[
1488 Item::Numeric(Numeric::Year, Pad::Zero),
1489 Item::Space(""),
1490 Item::Literal("-"),
1491 Item::Numeric(Numeric::Month, Pad::Zero),
1492 Item::Space(""),
1493 Item::Literal("-"),
1494 Item::Numeric(Numeric::Day, Pad::Zero),
1495 Item::Space(""),
1496 Item::Literal("T"), // XXX shouldn't this be case-insensitive?
1497 Item::Numeric(Numeric::Hour, Pad::Zero),
1498 Item::Space(""),
1499 Item::Literal(":"),
1500 Item::Numeric(Numeric::Minute, Pad::Zero),
1501 Item::Space(""),
1502 Item::Literal(":"),
1503 Item::Numeric(Numeric::Second, Pad::Zero),
1504 Item::Fixed(Fixed::Nanosecond),
1505 Item::Space(""),
1506 ];
1507
1508 let mut parsed = Parsed::new();
1509 parse(&mut parsed, s, ITEMS.iter())?;
1510 parsed.to_naive_datetime_with_offset(0)
1511 }
1512 }
1513
1514 #[cfg(all(test, any(feature = "rustc-serialize", feature = "serde")))]
test_encodable_json<F, E>(to_string: F) where F: Fn(&NaiveDateTime) -> Result<String, E>, E: ::std::fmt::Debug,1515 fn test_encodable_json<F, E>(to_string: F)
1516 where
1517 F: Fn(&NaiveDateTime) -> Result<String, E>,
1518 E: ::std::fmt::Debug,
1519 {
1520 use naive::{MAX_DATE, MIN_DATE};
1521
1522 assert_eq!(
1523 to_string(&NaiveDate::from_ymd(2016, 7, 8).and_hms_milli(9, 10, 48, 90)).ok(),
1524 Some(r#""2016-07-08T09:10:48.090""#.into())
1525 );
1526 assert_eq!(
1527 to_string(&NaiveDate::from_ymd(2014, 7, 24).and_hms(12, 34, 6)).ok(),
1528 Some(r#""2014-07-24T12:34:06""#.into())
1529 );
1530 assert_eq!(
1531 to_string(&NaiveDate::from_ymd(0, 1, 1).and_hms_milli(0, 0, 59, 1_000)).ok(),
1532 Some(r#""0000-01-01T00:00:60""#.into())
1533 );
1534 assert_eq!(
1535 to_string(&NaiveDate::from_ymd(-1, 12, 31).and_hms_nano(23, 59, 59, 7)).ok(),
1536 Some(r#""-0001-12-31T23:59:59.000000007""#.into())
1537 );
1538 assert_eq!(
1539 to_string(&MIN_DATE.and_hms(0, 0, 0)).ok(),
1540 Some(r#""-262144-01-01T00:00:00""#.into())
1541 );
1542 assert_eq!(
1543 to_string(&MAX_DATE.and_hms_nano(23, 59, 59, 1_999_999_999)).ok(),
1544 Some(r#""+262143-12-31T23:59:60.999999999""#.into())
1545 );
1546 }
1547
1548 #[cfg(all(test, any(feature = "rustc-serialize", feature = "serde")))]
test_decodable_json<F, E>(from_str: F) where F: Fn(&str) -> Result<NaiveDateTime, E>, E: ::std::fmt::Debug,1549 fn test_decodable_json<F, E>(from_str: F)
1550 where
1551 F: Fn(&str) -> Result<NaiveDateTime, E>,
1552 E: ::std::fmt::Debug,
1553 {
1554 use naive::{MAX_DATE, MIN_DATE};
1555
1556 assert_eq!(
1557 from_str(r#""2016-07-08T09:10:48.090""#).ok(),
1558 Some(NaiveDate::from_ymd(2016, 7, 8).and_hms_milli(9, 10, 48, 90))
1559 );
1560 assert_eq!(
1561 from_str(r#""2016-7-8T9:10:48.09""#).ok(),
1562 Some(NaiveDate::from_ymd(2016, 7, 8).and_hms_milli(9, 10, 48, 90))
1563 );
1564 assert_eq!(
1565 from_str(r#""2014-07-24T12:34:06""#).ok(),
1566 Some(NaiveDate::from_ymd(2014, 7, 24).and_hms(12, 34, 6))
1567 );
1568 assert_eq!(
1569 from_str(r#""0000-01-01T00:00:60""#).ok(),
1570 Some(NaiveDate::from_ymd(0, 1, 1).and_hms_milli(0, 0, 59, 1_000))
1571 );
1572 assert_eq!(
1573 from_str(r#""0-1-1T0:0:60""#).ok(),
1574 Some(NaiveDate::from_ymd(0, 1, 1).and_hms_milli(0, 0, 59, 1_000))
1575 );
1576 assert_eq!(
1577 from_str(r#""-0001-12-31T23:59:59.000000007""#).ok(),
1578 Some(NaiveDate::from_ymd(-1, 12, 31).and_hms_nano(23, 59, 59, 7))
1579 );
1580 assert_eq!(from_str(r#""-262144-01-01T00:00:00""#).ok(), Some(MIN_DATE.and_hms(0, 0, 0)));
1581 assert_eq!(
1582 from_str(r#""+262143-12-31T23:59:60.999999999""#).ok(),
1583 Some(MAX_DATE.and_hms_nano(23, 59, 59, 1_999_999_999))
1584 );
1585 assert_eq!(
1586 from_str(r#""+262143-12-31T23:59:60.9999999999997""#).ok(), // excess digits are ignored
1587 Some(MAX_DATE.and_hms_nano(23, 59, 59, 1_999_999_999))
1588 );
1589
1590 // bad formats
1591 assert!(from_str(r#""""#).is_err());
1592 assert!(from_str(r#""2016-07-08""#).is_err());
1593 assert!(from_str(r#""09:10:48.090""#).is_err());
1594 assert!(from_str(r#""20160708T091048.090""#).is_err());
1595 assert!(from_str(r#""2000-00-00T00:00:00""#).is_err());
1596 assert!(from_str(r#""2000-02-30T00:00:00""#).is_err());
1597 assert!(from_str(r#""2001-02-29T00:00:00""#).is_err());
1598 assert!(from_str(r#""2002-02-28T24:00:00""#).is_err());
1599 assert!(from_str(r#""2002-02-28T23:60:00""#).is_err());
1600 assert!(from_str(r#""2002-02-28T23:59:61""#).is_err());
1601 assert!(from_str(r#""2016-07-08T09:10:48,090""#).is_err());
1602 assert!(from_str(r#""2016-07-08 09:10:48.090""#).is_err());
1603 assert!(from_str(r#""2016-007-08T09:10:48.090""#).is_err());
1604 assert!(from_str(r#""yyyy-mm-ddThh:mm:ss.fffffffff""#).is_err());
1605 assert!(from_str(r#"20160708000000"#).is_err());
1606 assert!(from_str(r#"{}"#).is_err());
1607 // pre-0.3.0 rustc-serialize format is now invalid
1608 assert!(from_str(r#"{"date":{"ymdf":20},"time":{"secs":0,"frac":0}}"#).is_err());
1609 assert!(from_str(r#"null"#).is_err());
1610 }
1611
1612 #[cfg(all(test, feature = "rustc-serialize"))]
test_decodable_json_timestamp<F, E>(from_str: F) where F: Fn(&str) -> Result<rustc_serialize::TsSeconds, E>, E: ::std::fmt::Debug,1613 fn test_decodable_json_timestamp<F, E>(from_str: F)
1614 where
1615 F: Fn(&str) -> Result<rustc_serialize::TsSeconds, E>,
1616 E: ::std::fmt::Debug,
1617 {
1618 assert_eq!(
1619 *from_str("0").unwrap(),
1620 NaiveDate::from_ymd(1970, 1, 1).and_hms(0, 0, 0),
1621 "should parse integers as timestamps"
1622 );
1623 assert_eq!(
1624 *from_str("-1").unwrap(),
1625 NaiveDate::from_ymd(1969, 12, 31).and_hms(23, 59, 59),
1626 "should parse integers as timestamps"
1627 );
1628 }
1629
1630 #[cfg(feature = "rustc-serialize")]
1631 pub mod rustc_serialize {
1632 use super::NaiveDateTime;
1633 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
1634 use std::ops::Deref;
1635
1636 impl Encodable for NaiveDateTime {
encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error>1637 fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
1638 format!("{:?}", self).encode(s)
1639 }
1640 }
1641
1642 impl Decodable for NaiveDateTime {
decode<D: Decoder>(d: &mut D) -> Result<NaiveDateTime, D::Error>1643 fn decode<D: Decoder>(d: &mut D) -> Result<NaiveDateTime, D::Error> {
1644 d.read_str()?.parse().map_err(|_| d.error("invalid date time string"))
1645 }
1646 }
1647
1648 /// A `DateTime` that can be deserialized from a seconds-based timestamp
1649 #[derive(Debug)]
1650 #[deprecated(
1651 since = "1.4.2",
1652 note = "RustcSerialize will be removed before chrono 1.0, use Serde instead"
1653 )]
1654 pub struct TsSeconds(NaiveDateTime);
1655
1656 #[allow(deprecated)]
1657 impl From<TsSeconds> for NaiveDateTime {
1658 /// Pull the internal NaiveDateTime out
1659 #[allow(deprecated)]
from(obj: TsSeconds) -> NaiveDateTime1660 fn from(obj: TsSeconds) -> NaiveDateTime {
1661 obj.0
1662 }
1663 }
1664
1665 #[allow(deprecated)]
1666 impl Deref for TsSeconds {
1667 type Target = NaiveDateTime;
1668
1669 #[allow(deprecated)]
deref(&self) -> &Self::Target1670 fn deref(&self) -> &Self::Target {
1671 &self.0
1672 }
1673 }
1674
1675 #[allow(deprecated)]
1676 impl Decodable for TsSeconds {
1677 #[allow(deprecated)]
decode<D: Decoder>(d: &mut D) -> Result<TsSeconds, D::Error>1678 fn decode<D: Decoder>(d: &mut D) -> Result<TsSeconds, D::Error> {
1679 Ok(TsSeconds(
1680 NaiveDateTime::from_timestamp_opt(d.read_i64()?, 0)
1681 .ok_or_else(|| d.error("invalid timestamp"))?,
1682 ))
1683 }
1684 }
1685
1686 #[cfg(test)]
1687 use rustc_serialize::json;
1688
1689 #[test]
test_encodable()1690 fn test_encodable() {
1691 super::test_encodable_json(json::encode);
1692 }
1693
1694 #[test]
test_decodable()1695 fn test_decodable() {
1696 super::test_decodable_json(json::decode);
1697 }
1698
1699 #[test]
test_decodable_timestamps()1700 fn test_decodable_timestamps() {
1701 super::test_decodable_json_timestamp(json::decode);
1702 }
1703 }
1704
1705 /// Tools to help serializing/deserializing `NaiveDateTime`s
1706 #[cfg(feature = "serde")]
1707 pub mod serde {
1708 use super::NaiveDateTime;
1709 use core::fmt;
1710 use serdelib::{de, ser};
1711
1712 /// Serialize a `NaiveDateTime` as an RFC 3339 string
1713 ///
1714 /// See [the `serde` module](./serde/index.html) for alternate
1715 /// serialization formats.
1716 impl ser::Serialize for NaiveDateTime {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,1717 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1718 where
1719 S: ser::Serializer,
1720 {
1721 struct FormatWrapped<'a, D: 'a> {
1722 inner: &'a D,
1723 }
1724
1725 impl<'a, D: fmt::Debug> fmt::Display for FormatWrapped<'a, D> {
1726 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1727 self.inner.fmt(f)
1728 }
1729 }
1730
1731 serializer.collect_str(&FormatWrapped { inner: &self })
1732 }
1733 }
1734
1735 struct NaiveDateTimeVisitor;
1736
1737 impl<'de> de::Visitor<'de> for NaiveDateTimeVisitor {
1738 type Value = NaiveDateTime;
1739
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result1740 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1741 write!(formatter, "a formatted date and time string")
1742 }
1743
visit_str<E>(self, value: &str) -> Result<NaiveDateTime, E> where E: de::Error,1744 fn visit_str<E>(self, value: &str) -> Result<NaiveDateTime, E>
1745 where
1746 E: de::Error,
1747 {
1748 value.parse().map_err(E::custom)
1749 }
1750 }
1751
1752 impl<'de> de::Deserialize<'de> for NaiveDateTime {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: de::Deserializer<'de>,1753 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1754 where
1755 D: de::Deserializer<'de>,
1756 {
1757 deserializer.deserialize_str(NaiveDateTimeVisitor)
1758 }
1759 }
1760
1761 /// Used to serialize/deserialize from nanosecond-precision timestamps
1762 ///
1763 /// # Example:
1764 ///
1765 /// ```rust
1766 /// # // We mark this ignored so that we can test on 1.13 (which does not
1767 /// # // support custom derive), and run tests with --ignored on beta and
1768 /// # // nightly to actually trigger these.
1769 /// #
1770 /// # #[macro_use] extern crate serde_derive;
1771 /// # extern crate serde_json;
1772 /// # extern crate serde;
1773 /// # extern crate chrono;
1774 /// # use chrono::{TimeZone, NaiveDate, NaiveDateTime, Utc};
1775 /// use chrono::naive::serde::ts_nanoseconds;
1776 /// #[derive(Deserialize, Serialize)]
1777 /// struct S {
1778 /// #[serde(with = "ts_nanoseconds")]
1779 /// time: NaiveDateTime
1780 /// }
1781 ///
1782 /// # fn example() -> Result<S, serde_json::Error> {
1783 /// let time = NaiveDate::from_ymd(2018, 5, 17).and_hms_nano(02, 04, 59, 918355733);
1784 /// let my_s = S {
1785 /// time: time.clone(),
1786 /// };
1787 ///
1788 /// let as_string = serde_json::to_string(&my_s)?;
1789 /// assert_eq!(as_string, r#"{"time":1526522699918355733}"#);
1790 /// let my_s: S = serde_json::from_str(&as_string)?;
1791 /// assert_eq!(my_s.time, time);
1792 /// # Ok(my_s)
1793 /// # }
1794 /// # fn main() { example().unwrap(); }
1795 /// ```
1796 pub mod ts_nanoseconds {
1797 use core::fmt;
1798 use serdelib::{de, ser};
1799
1800 use {ne_timestamp, NaiveDateTime};
1801
1802 /// Serialize a UTC datetime into an integer number of nanoseconds since the epoch
1803 ///
1804 /// Intended for use with `serde`s `serialize_with` attribute.
1805 ///
1806 /// # Example:
1807 ///
1808 /// ```rust
1809 /// # // We mark this ignored so that we can test on 1.13 (which does not
1810 /// # // support custom derive), and run tests with --ignored on beta and
1811 /// # // nightly to actually trigger these.
1812 /// #
1813 /// # #[macro_use] extern crate serde_derive;
1814 /// # #[macro_use] extern crate serde_json;
1815 /// # #[macro_use] extern crate serde;
1816 /// # extern crate chrono;
1817 /// # use chrono::{TimeZone, NaiveDate, NaiveDateTime, Utc};
1818 /// # use serde::Serialize;
1819 /// use chrono::naive::serde::ts_nanoseconds::serialize as to_nano_ts;
1820 /// #[derive(Serialize)]
1821 /// struct S {
1822 /// #[serde(serialize_with = "to_nano_ts")]
1823 /// time: NaiveDateTime
1824 /// }
1825 ///
1826 /// # fn example() -> Result<String, serde_json::Error> {
1827 /// let my_s = S {
1828 /// time: NaiveDate::from_ymd(2018, 5, 17).and_hms_nano(02, 04, 59, 918355733),
1829 /// };
1830 /// let as_string = serde_json::to_string(&my_s)?;
1831 /// assert_eq!(as_string, r#"{"time":1526522699918355733}"#);
1832 /// # Ok(as_string)
1833 /// # }
1834 /// # fn main() { example().unwrap(); }
1835 /// ```
serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,1836 pub fn serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
1837 where
1838 S: ser::Serializer,
1839 {
1840 serializer.serialize_i64(dt.timestamp_nanos())
1841 }
1842
1843 /// Deserialize a `DateTime` from a nanoseconds timestamp
1844 ///
1845 /// Intended for use with `serde`s `deserialize_with` attribute.
1846 ///
1847 /// # Example:
1848 ///
1849 /// ```rust
1850 /// # // We mark this ignored so that we can test on 1.13 (which does not
1851 /// # // support custom derive), and run tests with --ignored on beta and
1852 /// # // nightly to actually trigger these.
1853 /// #
1854 /// # #[macro_use] extern crate serde_derive;
1855 /// # #[macro_use] extern crate serde_json;
1856 /// # extern crate serde;
1857 /// # extern crate chrono;
1858 /// # use chrono::{NaiveDateTime, Utc};
1859 /// # use serde::Deserialize;
1860 /// use chrono::naive::serde::ts_nanoseconds::deserialize as from_nano_ts;
1861 /// #[derive(Deserialize)]
1862 /// struct S {
1863 /// #[serde(deserialize_with = "from_nano_ts")]
1864 /// time: NaiveDateTime
1865 /// }
1866 ///
1867 /// # fn example() -> Result<S, serde_json::Error> {
1868 /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355733 }"#)?;
1869 /// # Ok(my_s)
1870 /// # }
1871 /// # fn main() { example().unwrap(); }
1872 /// ```
deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error> where D: de::Deserializer<'de>,1873 pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
1874 where
1875 D: de::Deserializer<'de>,
1876 {
1877 Ok(d.deserialize_i64(NaiveDateTimeFromNanoSecondsVisitor)?)
1878 }
1879
1880 struct NaiveDateTimeFromNanoSecondsVisitor;
1881
1882 impl<'de> de::Visitor<'de> for NaiveDateTimeFromNanoSecondsVisitor {
1883 type Value = NaiveDateTime;
1884
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result1885 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1886 formatter.write_str("a unix timestamp")
1887 }
1888
visit_i64<E>(self, value: i64) -> Result<NaiveDateTime, E> where E: de::Error,1889 fn visit_i64<E>(self, value: i64) -> Result<NaiveDateTime, E>
1890 where
1891 E: de::Error,
1892 {
1893 NaiveDateTime::from_timestamp_opt(
1894 value / 1_000_000_000,
1895 (value % 1_000_000_000) as u32,
1896 )
1897 .ok_or_else(|| E::custom(ne_timestamp(value)))
1898 }
1899
visit_u64<E>(self, value: u64) -> Result<NaiveDateTime, E> where E: de::Error,1900 fn visit_u64<E>(self, value: u64) -> Result<NaiveDateTime, E>
1901 where
1902 E: de::Error,
1903 {
1904 NaiveDateTime::from_timestamp_opt(
1905 value as i64 / 1_000_000_000,
1906 (value as i64 % 1_000_000_000) as u32,
1907 )
1908 .ok_or_else(|| E::custom(ne_timestamp(value)))
1909 }
1910 }
1911 }
1912
1913 /// Used to serialize/deserialize from millisecond-precision timestamps
1914 ///
1915 /// # Example:
1916 ///
1917 /// ```rust
1918 /// # // We mark this ignored so that we can test on 1.13 (which does not
1919 /// # // support custom derive), and run tests with --ignored on beta and
1920 /// # // nightly to actually trigger these.
1921 /// #
1922 /// # #[macro_use] extern crate serde_derive;
1923 /// # extern crate serde_json;
1924 /// # extern crate serde;
1925 /// # extern crate chrono;
1926 /// # use chrono::{TimeZone, NaiveDate, NaiveDateTime, Utc};
1927 /// use chrono::naive::serde::ts_milliseconds;
1928 /// #[derive(Deserialize, Serialize)]
1929 /// struct S {
1930 /// #[serde(with = "ts_milliseconds")]
1931 /// time: NaiveDateTime
1932 /// }
1933 ///
1934 /// # fn example() -> Result<S, serde_json::Error> {
1935 /// let time = NaiveDate::from_ymd(2018, 5, 17).and_hms_milli(02, 04, 59, 918);
1936 /// let my_s = S {
1937 /// time: time.clone(),
1938 /// };
1939 ///
1940 /// let as_string = serde_json::to_string(&my_s)?;
1941 /// assert_eq!(as_string, r#"{"time":1526522699918}"#);
1942 /// let my_s: S = serde_json::from_str(&as_string)?;
1943 /// assert_eq!(my_s.time, time);
1944 /// # Ok(my_s)
1945 /// # }
1946 /// # fn main() { example().unwrap(); }
1947 /// ```
1948 pub mod ts_milliseconds {
1949 use core::fmt;
1950 use serdelib::{de, ser};
1951
1952 use {ne_timestamp, NaiveDateTime};
1953
1954 /// Serialize a UTC datetime into an integer number of milliseconds since the epoch
1955 ///
1956 /// Intended for use with `serde`s `serialize_with` attribute.
1957 ///
1958 /// # Example:
1959 ///
1960 /// ```rust
1961 /// # // We mark this ignored so that we can test on 1.13 (which does not
1962 /// # // support custom derive), and run tests with --ignored on beta and
1963 /// # // nightly to actually trigger these.
1964 /// #
1965 /// # #[macro_use] extern crate serde_derive;
1966 /// # #[macro_use] extern crate serde_json;
1967 /// # #[macro_use] extern crate serde;
1968 /// # extern crate chrono;
1969 /// # use chrono::{TimeZone, NaiveDate, NaiveDateTime, Utc};
1970 /// # use serde::Serialize;
1971 /// use chrono::naive::serde::ts_milliseconds::serialize as to_milli_ts;
1972 /// #[derive(Serialize)]
1973 /// struct S {
1974 /// #[serde(serialize_with = "to_milli_ts")]
1975 /// time: NaiveDateTime
1976 /// }
1977 ///
1978 /// # fn example() -> Result<String, serde_json::Error> {
1979 /// let my_s = S {
1980 /// time: NaiveDate::from_ymd(2018, 5, 17).and_hms_milli(02, 04, 59, 918),
1981 /// };
1982 /// let as_string = serde_json::to_string(&my_s)?;
1983 /// assert_eq!(as_string, r#"{"time":1526522699918}"#);
1984 /// # Ok(as_string)
1985 /// # }
1986 /// # fn main() { example().unwrap(); }
1987 /// ```
serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,1988 pub fn serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
1989 where
1990 S: ser::Serializer,
1991 {
1992 serializer.serialize_i64(dt.timestamp_millis())
1993 }
1994
1995 /// Deserialize a `DateTime` from a milliseconds timestamp
1996 ///
1997 /// Intended for use with `serde`s `deserialize_with` attribute.
1998 ///
1999 /// # Example:
2000 ///
2001 /// ```rust
2002 /// # // We mark this ignored so that we can test on 1.13 (which does not
2003 /// # // support custom derive), and run tests with --ignored on beta and
2004 /// # // nightly to actually trigger these.
2005 /// #
2006 /// # #[macro_use] extern crate serde_derive;
2007 /// # #[macro_use] extern crate serde_json;
2008 /// # extern crate serde;
2009 /// # extern crate chrono;
2010 /// # use chrono::{NaiveDateTime, Utc};
2011 /// # use serde::Deserialize;
2012 /// use chrono::naive::serde::ts_milliseconds::deserialize as from_milli_ts;
2013 /// #[derive(Deserialize)]
2014 /// struct S {
2015 /// #[serde(deserialize_with = "from_milli_ts")]
2016 /// time: NaiveDateTime
2017 /// }
2018 ///
2019 /// # fn example() -> Result<S, serde_json::Error> {
2020 /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918 }"#)?;
2021 /// # Ok(my_s)
2022 /// # }
2023 /// # fn main() { example().unwrap(); }
2024 /// ```
deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error> where D: de::Deserializer<'de>,2025 pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
2026 where
2027 D: de::Deserializer<'de>,
2028 {
2029 Ok(d.deserialize_i64(NaiveDateTimeFromMilliSecondsVisitor)?)
2030 }
2031
2032 struct NaiveDateTimeFromMilliSecondsVisitor;
2033
2034 impl<'de> de::Visitor<'de> for NaiveDateTimeFromMilliSecondsVisitor {
2035 type Value = NaiveDateTime;
2036
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result2037 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
2038 formatter.write_str("a unix timestamp")
2039 }
2040
visit_i64<E>(self, value: i64) -> Result<NaiveDateTime, E> where E: de::Error,2041 fn visit_i64<E>(self, value: i64) -> Result<NaiveDateTime, E>
2042 where
2043 E: de::Error,
2044 {
2045 NaiveDateTime::from_timestamp_opt(value / 1000, ((value % 1000) * 1_000_000) as u32)
2046 .ok_or_else(|| E::custom(ne_timestamp(value)))
2047 }
2048
visit_u64<E>(self, value: u64) -> Result<NaiveDateTime, E> where E: de::Error,2049 fn visit_u64<E>(self, value: u64) -> Result<NaiveDateTime, E>
2050 where
2051 E: de::Error,
2052 {
2053 NaiveDateTime::from_timestamp_opt(
2054 (value / 1000) as i64,
2055 ((value % 1000) * 1_000_000) as u32,
2056 )
2057 .ok_or_else(|| E::custom(ne_timestamp(value)))
2058 }
2059 }
2060 }
2061
2062 /// Used to serialize/deserialize from second-precision timestamps
2063 ///
2064 /// # Example:
2065 ///
2066 /// ```rust
2067 /// # // We mark this ignored so that we can test on 1.13 (which does not
2068 /// # // support custom derive), and run tests with --ignored on beta and
2069 /// # // nightly to actually trigger these.
2070 /// #
2071 /// # #[macro_use] extern crate serde_derive;
2072 /// # extern crate serde_json;
2073 /// # extern crate serde;
2074 /// # extern crate chrono;
2075 /// # use chrono::{TimeZone, NaiveDate, NaiveDateTime, Utc};
2076 /// use chrono::naive::serde::ts_seconds;
2077 /// #[derive(Deserialize, Serialize)]
2078 /// struct S {
2079 /// #[serde(with = "ts_seconds")]
2080 /// time: NaiveDateTime
2081 /// }
2082 ///
2083 /// # fn example() -> Result<S, serde_json::Error> {
2084 /// let time = NaiveDate::from_ymd(2015, 5, 15).and_hms(10, 0, 0);
2085 /// let my_s = S {
2086 /// time: time.clone(),
2087 /// };
2088 ///
2089 /// let as_string = serde_json::to_string(&my_s)?;
2090 /// assert_eq!(as_string, r#"{"time":1431684000}"#);
2091 /// let my_s: S = serde_json::from_str(&as_string)?;
2092 /// assert_eq!(my_s.time, time);
2093 /// # Ok(my_s)
2094 /// # }
2095 /// # fn main() { example().unwrap(); }
2096 /// ```
2097 pub mod ts_seconds {
2098 use core::fmt;
2099 use serdelib::{de, ser};
2100
2101 use {ne_timestamp, NaiveDateTime};
2102
2103 /// Serialize a UTC datetime into an integer number of seconds since the epoch
2104 ///
2105 /// Intended for use with `serde`s `serialize_with` attribute.
2106 ///
2107 /// # Example:
2108 ///
2109 /// ```rust
2110 /// # // We mark this ignored so that we can test on 1.13 (which does not
2111 /// # // support custom derive), and run tests with --ignored on beta and
2112 /// # // nightly to actually trigger these.
2113 /// #
2114 /// # #[macro_use] extern crate serde_derive;
2115 /// # #[macro_use] extern crate serde_json;
2116 /// # #[macro_use] extern crate serde;
2117 /// # extern crate chrono;
2118 /// # use chrono::{TimeZone, NaiveDate, NaiveDateTime, Utc};
2119 /// # use serde::Serialize;
2120 /// use chrono::naive::serde::ts_seconds::serialize as to_ts;
2121 /// #[derive(Serialize)]
2122 /// struct S {
2123 /// #[serde(serialize_with = "to_ts")]
2124 /// time: NaiveDateTime
2125 /// }
2126 ///
2127 /// # fn example() -> Result<String, serde_json::Error> {
2128 /// let my_s = S {
2129 /// time: NaiveDate::from_ymd(2015, 5, 15).and_hms(10, 0, 0),
2130 /// };
2131 /// let as_string = serde_json::to_string(&my_s)?;
2132 /// assert_eq!(as_string, r#"{"time":1431684000}"#);
2133 /// # Ok(as_string)
2134 /// # }
2135 /// # fn main() { example().unwrap(); }
2136 /// ```
serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,2137 pub fn serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
2138 where
2139 S: ser::Serializer,
2140 {
2141 serializer.serialize_i64(dt.timestamp())
2142 }
2143
2144 /// Deserialize a `DateTime` from a seconds timestamp
2145 ///
2146 /// Intended for use with `serde`s `deserialize_with` attribute.
2147 ///
2148 /// # Example:
2149 ///
2150 /// ```rust
2151 /// # // We mark this ignored so that we can test on 1.13 (which does not
2152 /// # // support custom derive), and run tests with --ignored on beta and
2153 /// # // nightly to actually trigger these.
2154 /// #
2155 /// # #[macro_use] extern crate serde_derive;
2156 /// # #[macro_use] extern crate serde_json;
2157 /// # extern crate serde;
2158 /// # extern crate chrono;
2159 /// # use chrono::{NaiveDateTime, Utc};
2160 /// # use serde::Deserialize;
2161 /// use chrono::naive::serde::ts_seconds::deserialize as from_ts;
2162 /// #[derive(Deserialize)]
2163 /// struct S {
2164 /// #[serde(deserialize_with = "from_ts")]
2165 /// time: NaiveDateTime
2166 /// }
2167 ///
2168 /// # fn example() -> Result<S, serde_json::Error> {
2169 /// let my_s: S = serde_json::from_str(r#"{ "time": 1431684000 }"#)?;
2170 /// # Ok(my_s)
2171 /// # }
2172 /// # fn main() { example().unwrap(); }
2173 /// ```
deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error> where D: de::Deserializer<'de>,2174 pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
2175 where
2176 D: de::Deserializer<'de>,
2177 {
2178 Ok(d.deserialize_i64(NaiveDateTimeFromSecondsVisitor)?)
2179 }
2180
2181 struct NaiveDateTimeFromSecondsVisitor;
2182
2183 impl<'de> de::Visitor<'de> for NaiveDateTimeFromSecondsVisitor {
2184 type Value = NaiveDateTime;
2185
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result2186 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
2187 formatter.write_str("a unix timestamp")
2188 }
2189
visit_i64<E>(self, value: i64) -> Result<NaiveDateTime, E> where E: de::Error,2190 fn visit_i64<E>(self, value: i64) -> Result<NaiveDateTime, E>
2191 where
2192 E: de::Error,
2193 {
2194 NaiveDateTime::from_timestamp_opt(value, 0)
2195 .ok_or_else(|| E::custom(ne_timestamp(value)))
2196 }
2197
visit_u64<E>(self, value: u64) -> Result<NaiveDateTime, E> where E: de::Error,2198 fn visit_u64<E>(self, value: u64) -> Result<NaiveDateTime, E>
2199 where
2200 E: de::Error,
2201 {
2202 NaiveDateTime::from_timestamp_opt(value as i64, 0)
2203 .ok_or_else(|| E::custom(ne_timestamp(value)))
2204 }
2205 }
2206 }
2207
2208 #[cfg(test)]
2209 extern crate bincode;
2210 #[cfg(test)]
2211 extern crate serde_derive;
2212 #[cfg(test)]
2213 extern crate serde_json;
2214
2215 #[test]
test_serde_serialize()2216 fn test_serde_serialize() {
2217 super::test_encodable_json(self::serde_json::to_string);
2218 }
2219
2220 #[test]
test_serde_deserialize()2221 fn test_serde_deserialize() {
2222 super::test_decodable_json(|input| self::serde_json::from_str(&input));
2223 }
2224
2225 // Bincode is relevant to test separately from JSON because
2226 // it is not self-describing.
2227 #[test]
test_serde_bincode()2228 fn test_serde_bincode() {
2229 use self::bincode::{deserialize, serialize, Infinite};
2230 use naive::NaiveDate;
2231
2232 let dt = NaiveDate::from_ymd(2016, 7, 8).and_hms_milli(9, 10, 48, 90);
2233 let encoded = serialize(&dt, Infinite).unwrap();
2234 let decoded: NaiveDateTime = deserialize(&encoded).unwrap();
2235 assert_eq!(dt, decoded);
2236 }
2237
2238 #[test]
test_serde_bincode_optional()2239 fn test_serde_bincode_optional() {
2240 use self::bincode::{deserialize, serialize, Infinite};
2241 use self::serde_derive::{Deserialize, Serialize};
2242 use prelude::*;
2243 use serde::ts_nanoseconds_option;
2244
2245 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
2246 struct Test {
2247 one: Option<i64>,
2248 #[serde(with = "ts_nanoseconds_option")]
2249 two: Option<DateTime<Utc>>,
2250 }
2251
2252 let expected = Test { one: Some(1), two: Some(Utc.ymd(1970, 1, 1).and_hms(0, 1, 1)) };
2253 let bytes: Vec<u8> = serialize(&expected, Infinite).unwrap();
2254 let actual = deserialize::<Test>(&(bytes)).unwrap();
2255
2256 assert_eq!(expected, actual);
2257 }
2258 }
2259
2260 #[cfg(test)]
2261 mod tests {
2262 use super::NaiveDateTime;
2263 use naive::{NaiveDate, MAX_DATE, MIN_DATE};
2264 use oldtime::Duration;
2265 use std::i64;
2266 use Datelike;
2267
2268 #[test]
test_datetime_from_timestamp()2269 fn test_datetime_from_timestamp() {
2270 let from_timestamp = |secs| NaiveDateTime::from_timestamp_opt(secs, 0);
2271 let ymdhms = |y, m, d, h, n, s| NaiveDate::from_ymd(y, m, d).and_hms(h, n, s);
2272 assert_eq!(from_timestamp(-1), Some(ymdhms(1969, 12, 31, 23, 59, 59)));
2273 assert_eq!(from_timestamp(0), Some(ymdhms(1970, 1, 1, 0, 0, 0)));
2274 assert_eq!(from_timestamp(1), Some(ymdhms(1970, 1, 1, 0, 0, 1)));
2275 assert_eq!(from_timestamp(1_000_000_000), Some(ymdhms(2001, 9, 9, 1, 46, 40)));
2276 assert_eq!(from_timestamp(0x7fffffff), Some(ymdhms(2038, 1, 19, 3, 14, 7)));
2277 assert_eq!(from_timestamp(i64::MIN), None);
2278 assert_eq!(from_timestamp(i64::MAX), None);
2279 }
2280
2281 #[test]
test_datetime_add()2282 fn test_datetime_add() {
2283 fn check(
2284 (y, m, d, h, n, s): (i32, u32, u32, u32, u32, u32),
2285 rhs: Duration,
2286 result: Option<(i32, u32, u32, u32, u32, u32)>,
2287 ) {
2288 let lhs = NaiveDate::from_ymd(y, m, d).and_hms(h, n, s);
2289 let sum =
2290 result.map(|(y, m, d, h, n, s)| NaiveDate::from_ymd(y, m, d).and_hms(h, n, s));
2291 assert_eq!(lhs.checked_add_signed(rhs), sum);
2292 assert_eq!(lhs.checked_sub_signed(-rhs), sum);
2293 };
2294
2295 check(
2296 (2014, 5, 6, 7, 8, 9),
2297 Duration::seconds(3600 + 60 + 1),
2298 Some((2014, 5, 6, 8, 9, 10)),
2299 );
2300 check(
2301 (2014, 5, 6, 7, 8, 9),
2302 Duration::seconds(-(3600 + 60 + 1)),
2303 Some((2014, 5, 6, 6, 7, 8)),
2304 );
2305 check((2014, 5, 6, 7, 8, 9), Duration::seconds(86399), Some((2014, 5, 7, 7, 8, 8)));
2306 check((2014, 5, 6, 7, 8, 9), Duration::seconds(86_400 * 10), Some((2014, 5, 16, 7, 8, 9)));
2307 check((2014, 5, 6, 7, 8, 9), Duration::seconds(-86_400 * 10), Some((2014, 4, 26, 7, 8, 9)));
2308 check((2014, 5, 6, 7, 8, 9), Duration::seconds(86_400 * 10), Some((2014, 5, 16, 7, 8, 9)));
2309
2310 // overflow check
2311 // assumes that we have correct values for MAX/MIN_DAYS_FROM_YEAR_0 from `naive::date`.
2312 // (they are private constants, but the equivalence is tested in that module.)
2313 let max_days_from_year_0 = MAX_DATE.signed_duration_since(NaiveDate::from_ymd(0, 1, 1));
2314 check((0, 1, 1, 0, 0, 0), max_days_from_year_0, Some((MAX_DATE.year(), 12, 31, 0, 0, 0)));
2315 check(
2316 (0, 1, 1, 0, 0, 0),
2317 max_days_from_year_0 + Duration::seconds(86399),
2318 Some((MAX_DATE.year(), 12, 31, 23, 59, 59)),
2319 );
2320 check((0, 1, 1, 0, 0, 0), max_days_from_year_0 + Duration::seconds(86_400), None);
2321 check((0, 1, 1, 0, 0, 0), Duration::max_value(), None);
2322
2323 let min_days_from_year_0 = MIN_DATE.signed_duration_since(NaiveDate::from_ymd(0, 1, 1));
2324 check((0, 1, 1, 0, 0, 0), min_days_from_year_0, Some((MIN_DATE.year(), 1, 1, 0, 0, 0)));
2325 check((0, 1, 1, 0, 0, 0), min_days_from_year_0 - Duration::seconds(1), None);
2326 check((0, 1, 1, 0, 0, 0), Duration::min_value(), None);
2327 }
2328
2329 #[test]
test_datetime_sub()2330 fn test_datetime_sub() {
2331 let ymdhms = |y, m, d, h, n, s| NaiveDate::from_ymd(y, m, d).and_hms(h, n, s);
2332 let since = NaiveDateTime::signed_duration_since;
2333 assert_eq!(
2334 since(ymdhms(2014, 5, 6, 7, 8, 9), ymdhms(2014, 5, 6, 7, 8, 9)),
2335 Duration::zero()
2336 );
2337 assert_eq!(
2338 since(ymdhms(2014, 5, 6, 7, 8, 10), ymdhms(2014, 5, 6, 7, 8, 9)),
2339 Duration::seconds(1)
2340 );
2341 assert_eq!(
2342 since(ymdhms(2014, 5, 6, 7, 8, 9), ymdhms(2014, 5, 6, 7, 8, 10)),
2343 Duration::seconds(-1)
2344 );
2345 assert_eq!(
2346 since(ymdhms(2014, 5, 7, 7, 8, 9), ymdhms(2014, 5, 6, 7, 8, 10)),
2347 Duration::seconds(86399)
2348 );
2349 assert_eq!(
2350 since(ymdhms(2001, 9, 9, 1, 46, 39), ymdhms(1970, 1, 1, 0, 0, 0)),
2351 Duration::seconds(999_999_999)
2352 );
2353 }
2354
2355 #[test]
test_datetime_addassignment()2356 fn test_datetime_addassignment() {
2357 let ymdhms = |y, m, d, h, n, s| NaiveDate::from_ymd(y, m, d).and_hms(h, n, s);
2358 let mut date = ymdhms(2016, 10, 1, 10, 10, 10);
2359 date += Duration::minutes(10_000_000);
2360 assert_eq!(date, ymdhms(2035, 10, 6, 20, 50, 10));
2361 date += Duration::days(10);
2362 assert_eq!(date, ymdhms(2035, 10, 16, 20, 50, 10));
2363 }
2364
2365 #[test]
test_datetime_subassignment()2366 fn test_datetime_subassignment() {
2367 let ymdhms = |y, m, d, h, n, s| NaiveDate::from_ymd(y, m, d).and_hms(h, n, s);
2368 let mut date = ymdhms(2016, 10, 1, 10, 10, 10);
2369 date -= Duration::minutes(10_000_000);
2370 assert_eq!(date, ymdhms(1997, 9, 26, 23, 30, 10));
2371 date -= Duration::days(10);
2372 assert_eq!(date, ymdhms(1997, 9, 16, 23, 30, 10));
2373 }
2374
2375 #[test]
test_datetime_timestamp()2376 fn test_datetime_timestamp() {
2377 let to_timestamp =
2378 |y, m, d, h, n, s| NaiveDate::from_ymd(y, m, d).and_hms(h, n, s).timestamp();
2379 assert_eq!(to_timestamp(1969, 12, 31, 23, 59, 59), -1);
2380 assert_eq!(to_timestamp(1970, 1, 1, 0, 0, 0), 0);
2381 assert_eq!(to_timestamp(1970, 1, 1, 0, 0, 1), 1);
2382 assert_eq!(to_timestamp(2001, 9, 9, 1, 46, 40), 1_000_000_000);
2383 assert_eq!(to_timestamp(2038, 1, 19, 3, 14, 7), 0x7fffffff);
2384 }
2385
2386 #[test]
test_datetime_from_str()2387 fn test_datetime_from_str() {
2388 // valid cases
2389 let valid = [
2390 "2015-2-18T23:16:9.15",
2391 "-77-02-18T23:16:09",
2392 " +82701 - 05 - 6 T 15 : 9 : 60.898989898989 ",
2393 ];
2394 for &s in &valid {
2395 let d = match s.parse::<NaiveDateTime>() {
2396 Ok(d) => d,
2397 Err(e) => panic!("parsing `{}` has failed: {}", s, e),
2398 };
2399 let s_ = format!("{:?}", d);
2400 // `s` and `s_` may differ, but `s.parse()` and `s_.parse()` must be same
2401 let d_ = match s_.parse::<NaiveDateTime>() {
2402 Ok(d) => d,
2403 Err(e) => {
2404 panic!("`{}` is parsed into `{:?}`, but reparsing that has failed: {}", s, d, e)
2405 }
2406 };
2407 assert!(
2408 d == d_,
2409 "`{}` is parsed into `{:?}`, but reparsed result \
2410 `{:?}` does not match",
2411 s,
2412 d,
2413 d_
2414 );
2415 }
2416
2417 // some invalid cases
2418 // since `ParseErrorKind` is private, all we can do is to check if there was an error
2419 assert!("".parse::<NaiveDateTime>().is_err());
2420 assert!("x".parse::<NaiveDateTime>().is_err());
2421 assert!("15".parse::<NaiveDateTime>().is_err());
2422 assert!("15:8:9".parse::<NaiveDateTime>().is_err());
2423 assert!("15-8-9".parse::<NaiveDateTime>().is_err());
2424 assert!("2015-15-15T15:15:15".parse::<NaiveDateTime>().is_err());
2425 assert!("2012-12-12T12:12:12x".parse::<NaiveDateTime>().is_err());
2426 assert!("2012-123-12T12:12:12".parse::<NaiveDateTime>().is_err());
2427 assert!("+ 82701-123-12T12:12:12".parse::<NaiveDateTime>().is_err());
2428 assert!("+802701-123-12T12:12:12".parse::<NaiveDateTime>().is_err()); // out-of-bound
2429 }
2430
2431 #[test]
test_datetime_parse_from_str()2432 fn test_datetime_parse_from_str() {
2433 let ymdhms = |y, m, d, h, n, s| NaiveDate::from_ymd(y, m, d).and_hms(h, n, s);
2434 let ymdhmsn =
2435 |y, m, d, h, n, s, nano| NaiveDate::from_ymd(y, m, d).and_hms_nano(h, n, s, nano);
2436 assert_eq!(
2437 NaiveDateTime::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
2438 Ok(ymdhms(2014, 5, 7, 12, 34, 56))
2439 ); // ignore offset
2440 assert_eq!(
2441 NaiveDateTime::parse_from_str("2015-W06-1 000000", "%G-W%V-%u%H%M%S"),
2442 Ok(ymdhms(2015, 2, 2, 0, 0, 0))
2443 );
2444 assert_eq!(
2445 NaiveDateTime::parse_from_str(
2446 "Fri, 09 Aug 2013 23:54:35 GMT",
2447 "%a, %d %b %Y %H:%M:%S GMT"
2448 ),
2449 Ok(ymdhms(2013, 8, 9, 23, 54, 35))
2450 );
2451 assert!(NaiveDateTime::parse_from_str(
2452 "Sat, 09 Aug 2013 23:54:35 GMT",
2453 "%a, %d %b %Y %H:%M:%S GMT"
2454 )
2455 .is_err());
2456 assert!(NaiveDateTime::parse_from_str("2014-5-7 12:3456", "%Y-%m-%d %H:%M:%S").is_err());
2457 assert!(NaiveDateTime::parse_from_str("12:34:56", "%H:%M:%S").is_err()); // insufficient
2458 assert_eq!(
2459 NaiveDateTime::parse_from_str("1441497364", "%s"),
2460 Ok(ymdhms(2015, 9, 5, 23, 56, 4))
2461 );
2462 assert_eq!(
2463 NaiveDateTime::parse_from_str("1283929614.1234", "%s.%f"),
2464 Ok(ymdhmsn(2010, 9, 8, 7, 6, 54, 1234))
2465 );
2466 assert_eq!(
2467 NaiveDateTime::parse_from_str("1441497364.649", "%s%.3f"),
2468 Ok(ymdhmsn(2015, 9, 5, 23, 56, 4, 649000000))
2469 );
2470 assert_eq!(
2471 NaiveDateTime::parse_from_str("1497854303.087654", "%s%.6f"),
2472 Ok(ymdhmsn(2017, 6, 19, 6, 38, 23, 87654000))
2473 );
2474 assert_eq!(
2475 NaiveDateTime::parse_from_str("1437742189.918273645", "%s%.9f"),
2476 Ok(ymdhmsn(2015, 7, 24, 12, 49, 49, 918273645))
2477 );
2478 }
2479
2480 #[test]
test_datetime_format()2481 fn test_datetime_format() {
2482 let dt = NaiveDate::from_ymd(2010, 9, 8).and_hms_milli(7, 6, 54, 321);
2483 assert_eq!(dt.format("%c").to_string(), "Wed Sep 8 07:06:54 2010");
2484 assert_eq!(dt.format("%s").to_string(), "1283929614");
2485 assert_eq!(dt.format("%t%n%%%n%t").to_string(), "\t\n%\n\t");
2486
2487 // a horror of leap second: coming near to you.
2488 let dt = NaiveDate::from_ymd(2012, 6, 30).and_hms_milli(23, 59, 59, 1_000);
2489 assert_eq!(dt.format("%c").to_string(), "Sat Jun 30 23:59:60 2012");
2490 assert_eq!(dt.format("%s").to_string(), "1341100799"); // not 1341100800, it's intentional.
2491 }
2492
2493 #[test]
test_datetime_add_sub_invariant()2494 fn test_datetime_add_sub_invariant() {
2495 // issue #37
2496 let base = NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
2497 let t = -946684799990000;
2498 let time = base + Duration::microseconds(t);
2499 assert_eq!(t, time.signed_duration_since(base).num_microseconds().unwrap());
2500 }
2501
2502 #[test]
test_nanosecond_range()2503 fn test_nanosecond_range() {
2504 const A_BILLION: i64 = 1_000_000_000;
2505 let maximum = "2262-04-11T23:47:16.854775804";
2506 let parsed: NaiveDateTime = maximum.parse().unwrap();
2507 let nanos = parsed.timestamp_nanos();
2508 assert_eq!(
2509 parsed,
2510 NaiveDateTime::from_timestamp(nanos / A_BILLION, (nanos % A_BILLION) as u32)
2511 );
2512
2513 let minimum = "1677-09-21T00:12:44.000000000";
2514 let parsed: NaiveDateTime = minimum.parse().unwrap();
2515 let nanos = parsed.timestamp_nanos();
2516 assert_eq!(
2517 parsed,
2518 NaiveDateTime::from_timestamp(nanos / A_BILLION, (nanos % A_BILLION) as u32)
2519 );
2520 }
2521 }
2522