1 // This is a part of Chrono.
2 // See README.md and LICENSE.txt for details.
3
4 //! ISO 8601 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 oldtime::Duration as OldDuration;
11
12 use div::div_mod_floor;
13 #[cfg(any(feature = "alloc", feature = "std", test))]
14 use format::DelayedFormat;
15 use format::{parse, ParseError, ParseResult, Parsed, StrftimeItems};
16 use format::{Fixed, Item, Numeric, Pad};
17 use Timelike;
18
19 pub const MIN_TIME: NaiveTime = NaiveTime { secs: 0, frac: 0 };
20 pub const MAX_TIME: NaiveTime = NaiveTime { secs: 23 * 3600 + 59 * 60 + 59, frac: 999_999_999 };
21
22 /// ISO 8601 time without timezone.
23 /// Allows for the nanosecond precision and optional leap second representation.
24 ///
25 /// # Leap Second Handling
26 ///
27 /// Since 1960s, the manmade atomic clock has been so accurate that
28 /// it is much more accurate than Earth's own motion.
29 /// It became desirable to define the civil time in terms of the atomic clock,
30 /// but that risks the desynchronization of the civil time from Earth.
31 /// To account for this, the designers of the Coordinated Universal Time (UTC)
32 /// made that the UTC should be kept within 0.9 seconds of the observed Earth-bound time.
33 /// When the mean solar day is longer than the ideal (86,400 seconds),
34 /// the error slowly accumulates and it is necessary to add a **leap second**
35 /// to slow the UTC down a bit.
36 /// (We may also remove a second to speed the UTC up a bit, but it never happened.)
37 /// The leap second, if any, follows 23:59:59 of June 30 or December 31 in the UTC.
38 ///
39 /// Fast forward to the 21st century,
40 /// we have seen 26 leap seconds from January 1972 to December 2015.
41 /// Yes, 26 seconds. Probably you can read this paragraph within 26 seconds.
42 /// But those 26 seconds, and possibly more in the future, are never predictable,
43 /// and whether to add a leap second or not is known only before 6 months.
44 /// Internet-based clocks (via NTP) do account for known leap seconds,
45 /// but the system API normally doesn't (and often can't, with no network connection)
46 /// and there is no reliable way to retrieve leap second information.
47 ///
48 /// Chrono does not try to accurately implement leap seconds; it is impossible.
49 /// Rather, **it allows for leap seconds but behaves as if there are *no other* leap seconds.**
50 /// Various operations will ignore any possible leap second(s)
51 /// except when any of the operands were actually leap seconds.
52 ///
53 /// If you cannot tolerate this behavior,
54 /// you must use a separate `TimeZone` for the International Atomic Time (TAI).
55 /// TAI is like UTC but has no leap seconds, and thus slightly differs from UTC.
56 /// Chrono does not yet provide such implementation, but it is planned.
57 ///
58 /// ## Representing Leap Seconds
59 ///
60 /// The leap second is indicated via fractional seconds more than 1 second.
61 /// This makes possible to treat a leap second as the prior non-leap second
62 /// if you don't care about sub-second accuracy.
63 /// You should use the proper formatting to get the raw leap second.
64 ///
65 /// All methods accepting fractional seconds will accept such values.
66 ///
67 /// ~~~~
68 /// use chrono::{NaiveDate, NaiveTime, Utc, TimeZone};
69 ///
70 /// let t = NaiveTime::from_hms_milli(8, 59, 59, 1_000);
71 ///
72 /// let dt1 = NaiveDate::from_ymd(2015, 7, 1).and_hms_micro(8, 59, 59, 1_000_000);
73 ///
74 /// let dt2 = Utc.ymd(2015, 6, 30).and_hms_nano(23, 59, 59, 1_000_000_000);
75 /// # let _ = (t, dt1, dt2);
76 /// ~~~~
77 ///
78 /// Note that the leap second can happen anytime given an appropriate time zone;
79 /// 2015-07-01 01:23:60 would be a proper leap second if UTC+01:24 had existed.
80 /// Practically speaking, though, by the time of the first leap second on 1972-06-30,
81 /// every time zone offset around the world has standardized to the 5-minute alignment.
82 ///
83 /// ## Date And Time Arithmetics
84 ///
85 /// As a concrete example, let's assume that `03:00:60` and `04:00:60` are leap seconds.
86 /// In reality, of course, leap seconds are separated by at least 6 months.
87 /// We will also use some intuitive concise notations for the explanation.
88 ///
89 /// `Time + Duration`
90 /// (short for [`NaiveTime::overflowing_add_signed`](#method.overflowing_add_signed)):
91 ///
92 /// - `03:00:00 + 1s = 03:00:01`.
93 /// - `03:00:59 + 60s = 03:02:00`.
94 /// - `03:00:59 + 1s = 03:01:00`.
95 /// - `03:00:60 + 1s = 03:01:00`.
96 /// Note that the sum is identical to the previous.
97 /// - `03:00:60 + 60s = 03:01:59`.
98 /// - `03:00:60 + 61s = 03:02:00`.
99 /// - `03:00:60.1 + 0.8s = 03:00:60.9`.
100 ///
101 /// `Time - Duration`
102 /// (short for [`NaiveTime::overflowing_sub_signed`](#method.overflowing_sub_signed)):
103 ///
104 /// - `03:00:00 - 1s = 02:59:59`.
105 /// - `03:01:00 - 1s = 03:00:59`.
106 /// - `03:01:00 - 60s = 03:00:00`.
107 /// - `03:00:60 - 60s = 03:00:00`.
108 /// Note that the result is identical to the previous.
109 /// - `03:00:60.7 - 0.4s = 03:00:60.3`.
110 /// - `03:00:60.7 - 0.9s = 03:00:59.8`.
111 ///
112 /// `Time - Time`
113 /// (short for [`NaiveTime::signed_duration_since`](#method.signed_duration_since)):
114 ///
115 /// - `04:00:00 - 03:00:00 = 3600s`.
116 /// - `03:01:00 - 03:00:00 = 60s`.
117 /// - `03:00:60 - 03:00:00 = 60s`.
118 /// Note that the difference is identical to the previous.
119 /// - `03:00:60.6 - 03:00:59.4 = 1.2s`.
120 /// - `03:01:00 - 03:00:59.8 = 0.2s`.
121 /// - `03:01:00 - 03:00:60.5 = 0.5s`.
122 /// Note that the difference is larger than the previous,
123 /// even though the leap second clearly follows the previous whole second.
124 /// - `04:00:60.9 - 03:00:60.1 =
125 /// (04:00:60.9 - 04:00:00) + (04:00:00 - 03:01:00) + (03:01:00 - 03:00:60.1) =
126 /// 60.9s + 3540s + 0.9s = 3601.8s`.
127 ///
128 /// In general,
129 ///
130 /// - `Time + Duration` unconditionally equals to `Duration + Time`.
131 ///
132 /// - `Time - Duration` unconditionally equals to `Time + (-Duration)`.
133 ///
134 /// - `Time1 - Time2` unconditionally equals to `-(Time2 - Time1)`.
135 ///
136 /// - Associativity does not generally hold, because
137 /// `(Time + Duration1) - Duration2` no longer equals to `Time + (Duration1 - Duration2)`
138 /// for two positive durations.
139 ///
140 /// - As a special case, `(Time + Duration) - Duration` also does not equal to `Time`.
141 ///
142 /// - If you can assume that all durations have the same sign, however,
143 /// then the associativity holds:
144 /// `(Time + Duration1) + Duration2` equals to `Time + (Duration1 + Duration2)`
145 /// for two positive durations.
146 ///
147 /// ## Reading And Writing Leap Seconds
148 ///
149 /// The "typical" leap seconds on the minute boundary are
150 /// correctly handled both in the formatting and parsing.
151 /// The leap second in the human-readable representation
152 /// will be represented as the second part being 60, as required by ISO 8601.
153 ///
154 /// ~~~~
155 /// use chrono::{Utc, TimeZone};
156 ///
157 /// let dt = Utc.ymd(2015, 6, 30).and_hms_milli(23, 59, 59, 1_000);
158 /// assert_eq!(format!("{:?}", dt), "2015-06-30T23:59:60Z");
159 /// ~~~~
160 ///
161 /// There are hypothetical leap seconds not on the minute boundary
162 /// nevertheless supported by Chrono.
163 /// They are allowed for the sake of completeness and consistency;
164 /// there were several "exotic" time zone offsets with fractional minutes prior to UTC after all.
165 /// For such cases the human-readable representation is ambiguous
166 /// and would be read back to the next non-leap second.
167 ///
168 /// ~~~~
169 /// use chrono::{DateTime, Utc, TimeZone};
170 ///
171 /// let dt = Utc.ymd(2015, 6, 30).and_hms_milli(23, 56, 4, 1_000);
172 /// assert_eq!(format!("{:?}", dt), "2015-06-30T23:56:05Z");
173 ///
174 /// let dt = Utc.ymd(2015, 6, 30).and_hms(23, 56, 5);
175 /// assert_eq!(format!("{:?}", dt), "2015-06-30T23:56:05Z");
176 /// assert_eq!(DateTime::parse_from_rfc3339("2015-06-30T23:56:05Z").unwrap(), dt);
177 /// ~~~~
178 ///
179 /// Since Chrono alone cannot determine any existence of leap seconds,
180 /// **there is absolutely no guarantee that the leap second read has actually happened**.
181 #[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
182 pub struct NaiveTime {
183 secs: u32,
184 frac: u32,
185 }
186
187 impl NaiveTime {
188 /// Makes a new `NaiveTime` from hour, minute and second.
189 ///
190 /// No [leap second](#leap-second-handling) is allowed here;
191 /// use `NaiveTime::from_hms_*` methods with a subsecond parameter instead.
192 ///
193 /// Panics on invalid hour, minute and/or second.
194 ///
195 /// # Example
196 ///
197 /// ~~~~
198 /// use chrono::{NaiveTime, Timelike};
199 ///
200 /// let t = NaiveTime::from_hms(23, 56, 4);
201 /// assert_eq!(t.hour(), 23);
202 /// assert_eq!(t.minute(), 56);
203 /// assert_eq!(t.second(), 4);
204 /// assert_eq!(t.nanosecond(), 0);
205 /// ~~~~
206 #[inline]
from_hms(hour: u32, min: u32, sec: u32) -> NaiveTime207 pub fn from_hms(hour: u32, min: u32, sec: u32) -> NaiveTime {
208 NaiveTime::from_hms_opt(hour, min, sec).expect("invalid time")
209 }
210
211 /// Makes a new `NaiveTime` from hour, minute and second.
212 ///
213 /// No [leap second](#leap-second-handling) is allowed here;
214 /// use `NaiveTime::from_hms_*_opt` methods with a subsecond parameter instead.
215 ///
216 /// Returns `None` on invalid hour, minute and/or second.
217 ///
218 /// # Example
219 ///
220 /// ~~~~
221 /// use chrono::NaiveTime;
222 ///
223 /// let from_hms_opt = NaiveTime::from_hms_opt;
224 ///
225 /// assert!(from_hms_opt(0, 0, 0).is_some());
226 /// assert!(from_hms_opt(23, 59, 59).is_some());
227 /// assert!(from_hms_opt(24, 0, 0).is_none());
228 /// assert!(from_hms_opt(23, 60, 0).is_none());
229 /// assert!(from_hms_opt(23, 59, 60).is_none());
230 /// ~~~~
231 #[inline]
from_hms_opt(hour: u32, min: u32, sec: u32) -> Option<NaiveTime>232 pub fn from_hms_opt(hour: u32, min: u32, sec: u32) -> Option<NaiveTime> {
233 NaiveTime::from_hms_nano_opt(hour, min, sec, 0)
234 }
235
236 /// Makes a new `NaiveTime` from hour, minute, second and millisecond.
237 ///
238 /// The millisecond part can exceed 1,000
239 /// in order to represent the [leap second](#leap-second-handling).
240 ///
241 /// Panics on invalid hour, minute, second and/or millisecond.
242 ///
243 /// # Example
244 ///
245 /// ~~~~
246 /// use chrono::{NaiveTime, Timelike};
247 ///
248 /// let t = NaiveTime::from_hms_milli(23, 56, 4, 12);
249 /// assert_eq!(t.hour(), 23);
250 /// assert_eq!(t.minute(), 56);
251 /// assert_eq!(t.second(), 4);
252 /// assert_eq!(t.nanosecond(), 12_000_000);
253 /// ~~~~
254 #[inline]
from_hms_milli(hour: u32, min: u32, sec: u32, milli: u32) -> NaiveTime255 pub fn from_hms_milli(hour: u32, min: u32, sec: u32, milli: u32) -> NaiveTime {
256 NaiveTime::from_hms_milli_opt(hour, min, sec, milli).expect("invalid time")
257 }
258
259 /// Makes a new `NaiveTime` from hour, minute, second and millisecond.
260 ///
261 /// The millisecond part can exceed 1,000
262 /// in order to represent the [leap second](#leap-second-handling).
263 ///
264 /// Returns `None` on invalid hour, minute, second and/or millisecond.
265 ///
266 /// # Example
267 ///
268 /// ~~~~
269 /// use chrono::NaiveTime;
270 ///
271 /// let from_hmsm_opt = NaiveTime::from_hms_milli_opt;
272 ///
273 /// assert!(from_hmsm_opt(0, 0, 0, 0).is_some());
274 /// assert!(from_hmsm_opt(23, 59, 59, 999).is_some());
275 /// assert!(from_hmsm_opt(23, 59, 59, 1_999).is_some()); // a leap second after 23:59:59
276 /// assert!(from_hmsm_opt(24, 0, 0, 0).is_none());
277 /// assert!(from_hmsm_opt(23, 60, 0, 0).is_none());
278 /// assert!(from_hmsm_opt(23, 59, 60, 0).is_none());
279 /// assert!(from_hmsm_opt(23, 59, 59, 2_000).is_none());
280 /// ~~~~
281 #[inline]
from_hms_milli_opt(hour: u32, min: u32, sec: u32, milli: u32) -> Option<NaiveTime>282 pub fn from_hms_milli_opt(hour: u32, min: u32, sec: u32, milli: u32) -> Option<NaiveTime> {
283 milli
284 .checked_mul(1_000_000)
285 .and_then(|nano| NaiveTime::from_hms_nano_opt(hour, min, sec, nano))
286 }
287
288 /// Makes a new `NaiveTime` from hour, minute, second and microsecond.
289 ///
290 /// The microsecond part can exceed 1,000,000
291 /// in order to represent the [leap second](#leap-second-handling).
292 ///
293 /// Panics on invalid hour, minute, second and/or microsecond.
294 ///
295 /// # Example
296 ///
297 /// ~~~~
298 /// use chrono::{NaiveTime, Timelike};
299 ///
300 /// let t = NaiveTime::from_hms_micro(23, 56, 4, 12_345);
301 /// assert_eq!(t.hour(), 23);
302 /// assert_eq!(t.minute(), 56);
303 /// assert_eq!(t.second(), 4);
304 /// assert_eq!(t.nanosecond(), 12_345_000);
305 /// ~~~~
306 #[inline]
from_hms_micro(hour: u32, min: u32, sec: u32, micro: u32) -> NaiveTime307 pub fn from_hms_micro(hour: u32, min: u32, sec: u32, micro: u32) -> NaiveTime {
308 NaiveTime::from_hms_micro_opt(hour, min, sec, micro).expect("invalid time")
309 }
310
311 /// Makes a new `NaiveTime` from hour, minute, second and microsecond.
312 ///
313 /// The microsecond part can exceed 1,000,000
314 /// in order to represent the [leap second](#leap-second-handling).
315 ///
316 /// Returns `None` on invalid hour, minute, second and/or microsecond.
317 ///
318 /// # Example
319 ///
320 /// ~~~~
321 /// use chrono::NaiveTime;
322 ///
323 /// let from_hmsu_opt = NaiveTime::from_hms_micro_opt;
324 ///
325 /// assert!(from_hmsu_opt(0, 0, 0, 0).is_some());
326 /// assert!(from_hmsu_opt(23, 59, 59, 999_999).is_some());
327 /// assert!(from_hmsu_opt(23, 59, 59, 1_999_999).is_some()); // a leap second after 23:59:59
328 /// assert!(from_hmsu_opt(24, 0, 0, 0).is_none());
329 /// assert!(from_hmsu_opt(23, 60, 0, 0).is_none());
330 /// assert!(from_hmsu_opt(23, 59, 60, 0).is_none());
331 /// assert!(from_hmsu_opt(23, 59, 59, 2_000_000).is_none());
332 /// ~~~~
333 #[inline]
from_hms_micro_opt(hour: u32, min: u32, sec: u32, micro: u32) -> Option<NaiveTime>334 pub fn from_hms_micro_opt(hour: u32, min: u32, sec: u32, micro: u32) -> Option<NaiveTime> {
335 micro.checked_mul(1_000).and_then(|nano| NaiveTime::from_hms_nano_opt(hour, min, sec, nano))
336 }
337
338 /// Makes a new `NaiveTime` from hour, minute, second and nanosecond.
339 ///
340 /// The nanosecond part can exceed 1,000,000,000
341 /// in order to represent the [leap second](#leap-second-handling).
342 ///
343 /// Panics on invalid hour, minute, second and/or nanosecond.
344 ///
345 /// # Example
346 ///
347 /// ~~~~
348 /// use chrono::{NaiveTime, Timelike};
349 ///
350 /// let t = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
351 /// assert_eq!(t.hour(), 23);
352 /// assert_eq!(t.minute(), 56);
353 /// assert_eq!(t.second(), 4);
354 /// assert_eq!(t.nanosecond(), 12_345_678);
355 /// ~~~~
356 #[inline]
from_hms_nano(hour: u32, min: u32, sec: u32, nano: u32) -> NaiveTime357 pub fn from_hms_nano(hour: u32, min: u32, sec: u32, nano: u32) -> NaiveTime {
358 NaiveTime::from_hms_nano_opt(hour, min, sec, nano).expect("invalid time")
359 }
360
361 /// Makes a new `NaiveTime` from hour, minute, second and nanosecond.
362 ///
363 /// The nanosecond part can exceed 1,000,000,000
364 /// in order to represent the [leap second](#leap-second-handling).
365 ///
366 /// Returns `None` on invalid hour, minute, second and/or nanosecond.
367 ///
368 /// # Example
369 ///
370 /// ~~~~
371 /// use chrono::NaiveTime;
372 ///
373 /// let from_hmsn_opt = NaiveTime::from_hms_nano_opt;
374 ///
375 /// assert!(from_hmsn_opt(0, 0, 0, 0).is_some());
376 /// assert!(from_hmsn_opt(23, 59, 59, 999_999_999).is_some());
377 /// assert!(from_hmsn_opt(23, 59, 59, 1_999_999_999).is_some()); // a leap second after 23:59:59
378 /// assert!(from_hmsn_opt(24, 0, 0, 0).is_none());
379 /// assert!(from_hmsn_opt(23, 60, 0, 0).is_none());
380 /// assert!(from_hmsn_opt(23, 59, 60, 0).is_none());
381 /// assert!(from_hmsn_opt(23, 59, 59, 2_000_000_000).is_none());
382 /// ~~~~
383 #[inline]
from_hms_nano_opt(hour: u32, min: u32, sec: u32, nano: u32) -> Option<NaiveTime>384 pub fn from_hms_nano_opt(hour: u32, min: u32, sec: u32, nano: u32) -> Option<NaiveTime> {
385 if hour >= 24 || min >= 60 || sec >= 60 || nano >= 2_000_000_000 {
386 return None;
387 }
388 let secs = hour * 3600 + min * 60 + sec;
389 Some(NaiveTime { secs: secs, frac: nano })
390 }
391
392 /// Makes a new `NaiveTime` from the number of seconds since midnight and nanosecond.
393 ///
394 /// The nanosecond part can exceed 1,000,000,000
395 /// in order to represent the [leap second](#leap-second-handling).
396 ///
397 /// Panics on invalid number of seconds and/or nanosecond.
398 ///
399 /// # Example
400 ///
401 /// ~~~~
402 /// use chrono::{NaiveTime, Timelike};
403 ///
404 /// let t = NaiveTime::from_num_seconds_from_midnight(86164, 12_345_678);
405 /// assert_eq!(t.hour(), 23);
406 /// assert_eq!(t.minute(), 56);
407 /// assert_eq!(t.second(), 4);
408 /// assert_eq!(t.nanosecond(), 12_345_678);
409 /// ~~~~
410 #[inline]
from_num_seconds_from_midnight(secs: u32, nano: u32) -> NaiveTime411 pub fn from_num_seconds_from_midnight(secs: u32, nano: u32) -> NaiveTime {
412 NaiveTime::from_num_seconds_from_midnight_opt(secs, nano).expect("invalid time")
413 }
414
415 /// Makes a new `NaiveTime` from the number of seconds since midnight and nanosecond.
416 ///
417 /// The nanosecond part can exceed 1,000,000,000
418 /// in order to represent the [leap second](#leap-second-handling).
419 ///
420 /// Returns `None` on invalid number of seconds and/or nanosecond.
421 ///
422 /// # Example
423 ///
424 /// ~~~~
425 /// use chrono::NaiveTime;
426 ///
427 /// let from_nsecs_opt = NaiveTime::from_num_seconds_from_midnight_opt;
428 ///
429 /// assert!(from_nsecs_opt(0, 0).is_some());
430 /// assert!(from_nsecs_opt(86399, 999_999_999).is_some());
431 /// assert!(from_nsecs_opt(86399, 1_999_999_999).is_some()); // a leap second after 23:59:59
432 /// assert!(from_nsecs_opt(86_400, 0).is_none());
433 /// assert!(from_nsecs_opt(86399, 2_000_000_000).is_none());
434 /// ~~~~
435 #[inline]
from_num_seconds_from_midnight_opt(secs: u32, nano: u32) -> Option<NaiveTime>436 pub fn from_num_seconds_from_midnight_opt(secs: u32, nano: u32) -> Option<NaiveTime> {
437 if secs >= 86_400 || nano >= 2_000_000_000 {
438 return None;
439 }
440 Some(NaiveTime { secs: secs, frac: nano })
441 }
442
443 /// Parses a string with the specified format string and returns a new `NaiveTime`.
444 /// See the [`format::strftime` module](../format/strftime/index.html)
445 /// on the supported escape sequences.
446 ///
447 /// # Example
448 ///
449 /// ~~~~
450 /// use chrono::NaiveTime;
451 ///
452 /// let parse_from_str = NaiveTime::parse_from_str;
453 ///
454 /// assert_eq!(parse_from_str("23:56:04", "%H:%M:%S"),
455 /// Ok(NaiveTime::from_hms(23, 56, 4)));
456 /// assert_eq!(parse_from_str("pm012345.6789", "%p%I%M%S%.f"),
457 /// Ok(NaiveTime::from_hms_micro(13, 23, 45, 678_900)));
458 /// ~~~~
459 ///
460 /// Date and offset is ignored for the purpose of parsing.
461 ///
462 /// ~~~~
463 /// # use chrono::NaiveTime;
464 /// # let parse_from_str = NaiveTime::parse_from_str;
465 /// assert_eq!(parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
466 /// Ok(NaiveTime::from_hms(12, 34, 56)));
467 /// ~~~~
468 ///
469 /// [Leap seconds](#leap-second-handling) are correctly handled by
470 /// treating any time of the form `hh:mm:60` as a leap second.
471 /// (This equally applies to the formatting, so the round trip is possible.)
472 ///
473 /// ~~~~
474 /// # use chrono::NaiveTime;
475 /// # let parse_from_str = NaiveTime::parse_from_str;
476 /// assert_eq!(parse_from_str("08:59:60.123", "%H:%M:%S%.f"),
477 /// Ok(NaiveTime::from_hms_milli(8, 59, 59, 1_123)));
478 /// ~~~~
479 ///
480 /// Missing seconds are assumed to be zero,
481 /// but out-of-bound times or insufficient fields are errors otherwise.
482 ///
483 /// ~~~~
484 /// # use chrono::NaiveTime;
485 /// # let parse_from_str = NaiveTime::parse_from_str;
486 /// assert_eq!(parse_from_str("7:15", "%H:%M"),
487 /// Ok(NaiveTime::from_hms(7, 15, 0)));
488 ///
489 /// assert!(parse_from_str("04m33s", "%Mm%Ss").is_err());
490 /// assert!(parse_from_str("12", "%H").is_err());
491 /// assert!(parse_from_str("17:60", "%H:%M").is_err());
492 /// assert!(parse_from_str("24:00:00", "%H:%M:%S").is_err());
493 /// ~~~~
494 ///
495 /// All parsed fields should be consistent to each other, otherwise it's an error.
496 /// Here `%H` is for 24-hour clocks, unlike `%I`,
497 /// and thus can be independently determined without AM/PM.
498 ///
499 /// ~~~~
500 /// # use chrono::NaiveTime;
501 /// # let parse_from_str = NaiveTime::parse_from_str;
502 /// assert!(parse_from_str("13:07 AM", "%H:%M %p").is_err());
503 /// ~~~~
parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveTime>504 pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveTime> {
505 let mut parsed = Parsed::new();
506 parse(&mut parsed, s, StrftimeItems::new(fmt))?;
507 parsed.to_naive_time()
508 }
509
510 /// Adds given `Duration` to the current time,
511 /// and also returns the number of *seconds*
512 /// in the integral number of days ignored from the addition.
513 /// (We cannot return `Duration` because it is subject to overflow or underflow.)
514 ///
515 /// # Example
516 ///
517 /// ~~~~
518 /// # extern crate chrono; fn main() {
519 /// use chrono::{Duration, NaiveTime};
520 ///
521 /// let from_hms = NaiveTime::from_hms;
522 ///
523 /// assert_eq!(from_hms(3, 4, 5).overflowing_add_signed(Duration::hours(11)),
524 /// (from_hms(14, 4, 5), 0));
525 /// assert_eq!(from_hms(3, 4, 5).overflowing_add_signed(Duration::hours(23)),
526 /// (from_hms(2, 4, 5), 86_400));
527 /// assert_eq!(from_hms(3, 4, 5).overflowing_add_signed(Duration::hours(-7)),
528 /// (from_hms(20, 4, 5), -86_400));
529 /// # }
530 /// ~~~~
531 #[cfg_attr(feature = "cargo-clippy", allow(cyclomatic_complexity))]
overflowing_add_signed(&self, mut rhs: OldDuration) -> (NaiveTime, i64)532 pub fn overflowing_add_signed(&self, mut rhs: OldDuration) -> (NaiveTime, i64) {
533 let mut secs = self.secs;
534 let mut frac = self.frac;
535
536 // check if `self` is a leap second and adding `rhs` would escape that leap second.
537 // if it's the case, update `self` and `rhs` to involve no leap second;
538 // otherwise the addition immediately finishes.
539 if frac >= 1_000_000_000 {
540 let rfrac = 2_000_000_000 - frac;
541 if rhs >= OldDuration::nanoseconds(i64::from(rfrac)) {
542 rhs = rhs - OldDuration::nanoseconds(i64::from(rfrac));
543 secs += 1;
544 frac = 0;
545 } else if rhs < OldDuration::nanoseconds(-i64::from(frac)) {
546 rhs = rhs + OldDuration::nanoseconds(i64::from(frac));
547 frac = 0;
548 } else {
549 frac = (i64::from(frac) + rhs.num_nanoseconds().unwrap()) as u32;
550 debug_assert!(frac < 2_000_000_000);
551 return (NaiveTime { secs: secs, frac: frac }, 0);
552 }
553 }
554 debug_assert!(secs <= 86_400);
555 debug_assert!(frac < 1_000_000_000);
556
557 let rhssecs = rhs.num_seconds();
558 let rhsfrac = (rhs - OldDuration::seconds(rhssecs)).num_nanoseconds().unwrap();
559 debug_assert_eq!(OldDuration::seconds(rhssecs) + OldDuration::nanoseconds(rhsfrac), rhs);
560 let rhssecsinday = rhssecs % 86_400;
561 let mut morerhssecs = rhssecs - rhssecsinday;
562 let rhssecs = rhssecsinday as i32;
563 let rhsfrac = rhsfrac as i32;
564 debug_assert!(-86_400 < rhssecs && rhssecs < 86_400);
565 debug_assert_eq!(morerhssecs % 86_400, 0);
566 debug_assert!(-1_000_000_000 < rhsfrac && rhsfrac < 1_000_000_000);
567
568 let mut secs = secs as i32 + rhssecs;
569 let mut frac = frac as i32 + rhsfrac;
570 debug_assert!(-86_400 < secs && secs < 2 * 86_400);
571 debug_assert!(-1_000_000_000 < frac && frac < 2_000_000_000);
572
573 if frac < 0 {
574 frac += 1_000_000_000;
575 secs -= 1;
576 } else if frac >= 1_000_000_000 {
577 frac -= 1_000_000_000;
578 secs += 1;
579 }
580 debug_assert!(-86_400 <= secs && secs < 2 * 86_400);
581 debug_assert!(0 <= frac && frac < 1_000_000_000);
582
583 if secs < 0 {
584 secs += 86_400;
585 morerhssecs -= 86_400;
586 } else if secs >= 86_400 {
587 secs -= 86_400;
588 morerhssecs += 86_400;
589 }
590 debug_assert!(0 <= secs && secs < 86_400);
591
592 (NaiveTime { secs: secs as u32, frac: frac as u32 }, morerhssecs)
593 }
594
595 /// Subtracts given `Duration` from the current time,
596 /// and also returns the number of *seconds*
597 /// in the integral number of days ignored from the subtraction.
598 /// (We cannot return `Duration` because it is subject to overflow or underflow.)
599 ///
600 /// # Example
601 ///
602 /// ~~~~
603 /// # extern crate chrono; fn main() {
604 /// use chrono::{Duration, NaiveTime};
605 ///
606 /// let from_hms = NaiveTime::from_hms;
607 ///
608 /// assert_eq!(from_hms(3, 4, 5).overflowing_sub_signed(Duration::hours(2)),
609 /// (from_hms(1, 4, 5), 0));
610 /// assert_eq!(from_hms(3, 4, 5).overflowing_sub_signed(Duration::hours(17)),
611 /// (from_hms(10, 4, 5), 86_400));
612 /// assert_eq!(from_hms(3, 4, 5).overflowing_sub_signed(Duration::hours(-22)),
613 /// (from_hms(1, 4, 5), -86_400));
614 /// # }
615 /// ~~~~
616 #[inline]
overflowing_sub_signed(&self, rhs: OldDuration) -> (NaiveTime, i64)617 pub fn overflowing_sub_signed(&self, rhs: OldDuration) -> (NaiveTime, i64) {
618 let (time, rhs) = self.overflowing_add_signed(-rhs);
619 (time, -rhs) // safe to negate, rhs is within +/- (2^63 / 1000)
620 }
621
622 /// Subtracts another `NaiveTime` from the current time.
623 /// Returns a `Duration` within +/- 1 day.
624 /// This does not overflow or underflow at all.
625 ///
626 /// As a part of Chrono's [leap second handling](#leap-second-handling),
627 /// the subtraction assumes that **there is no leap second ever**,
628 /// except when any of the `NaiveTime`s themselves represents a leap second
629 /// in which case the assumption becomes that
630 /// **there are exactly one (or two) leap second(s) ever**.
631 ///
632 /// # Example
633 ///
634 /// ~~~~
635 /// # extern crate chrono; fn main() {
636 /// use chrono::{Duration, NaiveTime};
637 ///
638 /// let from_hmsm = NaiveTime::from_hms_milli;
639 /// let since = NaiveTime::signed_duration_since;
640 ///
641 /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 7, 900)),
642 /// Duration::zero());
643 /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 7, 875)),
644 /// Duration::milliseconds(25));
645 /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 6, 925)),
646 /// Duration::milliseconds(975));
647 /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 0, 900)),
648 /// Duration::seconds(7));
649 /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 0, 7, 900)),
650 /// Duration::seconds(5 * 60));
651 /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(0, 5, 7, 900)),
652 /// Duration::seconds(3 * 3600));
653 /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(4, 5, 7, 900)),
654 /// Duration::seconds(-3600));
655 /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(2, 4, 6, 800)),
656 /// Duration::seconds(3600 + 60 + 1) + Duration::milliseconds(100));
657 /// # }
658 /// ~~~~
659 ///
660 /// Leap seconds are handled, but the subtraction assumes that
661 /// there were no other leap seconds happened.
662 ///
663 /// ~~~~
664 /// # extern crate chrono; fn main() {
665 /// # use chrono::{Duration, NaiveTime};
666 /// # let from_hmsm = NaiveTime::from_hms_milli;
667 /// # let since = NaiveTime::signed_duration_since;
668 /// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(3, 0, 59, 0)),
669 /// Duration::seconds(1));
670 /// assert_eq!(since(from_hmsm(3, 0, 59, 1_500), from_hmsm(3, 0, 59, 0)),
671 /// Duration::milliseconds(1500));
672 /// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(3, 0, 0, 0)),
673 /// Duration::seconds(60));
674 /// assert_eq!(since(from_hmsm(3, 0, 0, 0), from_hmsm(2, 59, 59, 1_000)),
675 /// Duration::seconds(1));
676 /// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(2, 59, 59, 1_000)),
677 /// Duration::seconds(61));
678 /// # }
679 /// ~~~~
signed_duration_since(self, rhs: NaiveTime) -> OldDuration680 pub fn signed_duration_since(self, rhs: NaiveTime) -> OldDuration {
681 // | | :leap| | | | | | | :leap| |
682 // | | : | | | | | | | : | |
683 // ----+----+-----*---+----+----+----+----+----+----+-------*-+----+----
684 // | `rhs` | | `self`
685 // |======================================>| |
686 // | | `self.secs - rhs.secs` |`self.frac`
687 // |====>| | |======>|
688 // `rhs.frac`|========================================>|
689 // | | | `self - rhs` | |
690
691 use core::cmp::Ordering;
692
693 let secs = i64::from(self.secs) - i64::from(rhs.secs);
694 let frac = i64::from(self.frac) - i64::from(rhs.frac);
695
696 // `secs` may contain a leap second yet to be counted
697 let adjust = match self.secs.cmp(&rhs.secs) {
698 Ordering::Greater => {
699 if rhs.frac >= 1_000_000_000 {
700 1
701 } else {
702 0
703 }
704 }
705 Ordering::Equal => 0,
706 Ordering::Less => {
707 if self.frac >= 1_000_000_000 {
708 -1
709 } else {
710 0
711 }
712 }
713 };
714
715 OldDuration::seconds(secs + adjust) + OldDuration::nanoseconds(frac)
716 }
717
718 /// Formats the time with the specified formatting items.
719 /// Otherwise it is the same as the ordinary [`format`](#method.format) method.
720 ///
721 /// The `Iterator` of items should be `Clone`able,
722 /// since the resulting `DelayedFormat` value may be formatted multiple times.
723 ///
724 /// # Example
725 ///
726 /// ~~~~
727 /// use chrono::NaiveTime;
728 /// use chrono::format::strftime::StrftimeItems;
729 ///
730 /// let fmt = StrftimeItems::new("%H:%M:%S");
731 /// let t = NaiveTime::from_hms(23, 56, 4);
732 /// assert_eq!(t.format_with_items(fmt.clone()).to_string(), "23:56:04");
733 /// assert_eq!(t.format("%H:%M:%S").to_string(), "23:56:04");
734 /// ~~~~
735 ///
736 /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
737 ///
738 /// ~~~~
739 /// # use chrono::NaiveTime;
740 /// # use chrono::format::strftime::StrftimeItems;
741 /// # let fmt = StrftimeItems::new("%H:%M:%S").clone();
742 /// # let t = NaiveTime::from_hms(23, 56, 4);
743 /// assert_eq!(format!("{}", t.format_with_items(fmt)), "23:56:04");
744 /// ~~~~
745 #[cfg(any(feature = "alloc", feature = "std", test))]
746 #[inline]
format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat<I> where I: Iterator<Item = B> + Clone, B: Borrow<Item<'a>>,747 pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat<I>
748 where
749 I: Iterator<Item = B> + Clone,
750 B: Borrow<Item<'a>>,
751 {
752 DelayedFormat::new(None, Some(*self), items)
753 }
754
755 /// Formats the time with the specified format string.
756 /// See the [`format::strftime` module](../format/strftime/index.html)
757 /// on the supported escape sequences.
758 ///
759 /// This returns a `DelayedFormat`,
760 /// which gets converted to a string only when actual formatting happens.
761 /// You may use the `to_string` method to get a `String`,
762 /// or just feed it into `print!` and other formatting macros.
763 /// (In this way it avoids the redundant memory allocation.)
764 ///
765 /// A wrong format string does *not* issue an error immediately.
766 /// Rather, converting or formatting the `DelayedFormat` fails.
767 /// You are recommended to immediately use `DelayedFormat` for this reason.
768 ///
769 /// # Example
770 ///
771 /// ~~~~
772 /// use chrono::NaiveTime;
773 ///
774 /// let t = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
775 /// assert_eq!(t.format("%H:%M:%S").to_string(), "23:56:04");
776 /// assert_eq!(t.format("%H:%M:%S%.6f").to_string(), "23:56:04.012345");
777 /// assert_eq!(t.format("%-I:%M %p").to_string(), "11:56 PM");
778 /// ~~~~
779 ///
780 /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
781 ///
782 /// ~~~~
783 /// # use chrono::NaiveTime;
784 /// # let t = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
785 /// assert_eq!(format!("{}", t.format("%H:%M:%S")), "23:56:04");
786 /// assert_eq!(format!("{}", t.format("%H:%M:%S%.6f")), "23:56:04.012345");
787 /// assert_eq!(format!("{}", t.format("%-I:%M %p")), "11:56 PM");
788 /// ~~~~
789 #[cfg(any(feature = "alloc", feature = "std", test))]
790 #[inline]
format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>>791 pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
792 self.format_with_items(StrftimeItems::new(fmt))
793 }
794
795 /// Returns a triple of the hour, minute and second numbers.
hms(&self) -> (u32, u32, u32)796 fn hms(&self) -> (u32, u32, u32) {
797 let (mins, sec) = div_mod_floor(self.secs, 60);
798 let (hour, min) = div_mod_floor(mins, 60);
799 (hour, min, sec)
800 }
801 }
802
803 impl Timelike for NaiveTime {
804 /// Returns the hour number from 0 to 23.
805 ///
806 /// # Example
807 ///
808 /// ~~~~
809 /// use chrono::{NaiveTime, Timelike};
810 ///
811 /// assert_eq!(NaiveTime::from_hms(0, 0, 0).hour(), 0);
812 /// assert_eq!(NaiveTime::from_hms_nano(23, 56, 4, 12_345_678).hour(), 23);
813 /// ~~~~
814 #[inline]
hour(&self) -> u32815 fn hour(&self) -> u32 {
816 self.hms().0
817 }
818
819 /// Returns the minute number from 0 to 59.
820 ///
821 /// # Example
822 ///
823 /// ~~~~
824 /// use chrono::{NaiveTime, Timelike};
825 ///
826 /// assert_eq!(NaiveTime::from_hms(0, 0, 0).minute(), 0);
827 /// assert_eq!(NaiveTime::from_hms_nano(23, 56, 4, 12_345_678).minute(), 56);
828 /// ~~~~
829 #[inline]
minute(&self) -> u32830 fn minute(&self) -> u32 {
831 self.hms().1
832 }
833
834 /// Returns the second number from 0 to 59.
835 ///
836 /// # Example
837 ///
838 /// ~~~~
839 /// use chrono::{NaiveTime, Timelike};
840 ///
841 /// assert_eq!(NaiveTime::from_hms(0, 0, 0).second(), 0);
842 /// assert_eq!(NaiveTime::from_hms_nano(23, 56, 4, 12_345_678).second(), 4);
843 /// ~~~~
844 ///
845 /// This method never returns 60 even when it is a leap second.
846 /// ([Why?](#leap-second-handling))
847 /// Use the proper [formatting method](#method.format) to get a human-readable representation.
848 ///
849 /// ~~~~
850 /// # use chrono::{NaiveTime, Timelike};
851 /// let leap = NaiveTime::from_hms_milli(23, 59, 59, 1_000);
852 /// assert_eq!(leap.second(), 59);
853 /// assert_eq!(leap.format("%H:%M:%S").to_string(), "23:59:60");
854 /// ~~~~
855 #[inline]
second(&self) -> u32856 fn second(&self) -> u32 {
857 self.hms().2
858 }
859
860 /// Returns the number of nanoseconds since the whole non-leap second.
861 /// The range from 1,000,000,000 to 1,999,999,999 represents
862 /// the [leap second](#leap-second-handling).
863 ///
864 /// # Example
865 ///
866 /// ~~~~
867 /// use chrono::{NaiveTime, Timelike};
868 ///
869 /// assert_eq!(NaiveTime::from_hms(0, 0, 0).nanosecond(), 0);
870 /// assert_eq!(NaiveTime::from_hms_nano(23, 56, 4, 12_345_678).nanosecond(), 12_345_678);
871 /// ~~~~
872 ///
873 /// Leap seconds may have seemingly out-of-range return values.
874 /// You can reduce the range with `time.nanosecond() % 1_000_000_000`, or
875 /// use the proper [formatting method](#method.format) to get a human-readable representation.
876 ///
877 /// ~~~~
878 /// # use chrono::{NaiveTime, Timelike};
879 /// let leap = NaiveTime::from_hms_milli(23, 59, 59, 1_000);
880 /// assert_eq!(leap.nanosecond(), 1_000_000_000);
881 /// assert_eq!(leap.format("%H:%M:%S%.9f").to_string(), "23:59:60.000000000");
882 /// ~~~~
883 #[inline]
nanosecond(&self) -> u32884 fn nanosecond(&self) -> u32 {
885 self.frac
886 }
887
888 /// Makes a new `NaiveTime` with the hour number changed.
889 ///
890 /// Returns `None` when the resulting `NaiveTime` would be invalid.
891 ///
892 /// # Example
893 ///
894 /// ~~~~
895 /// use chrono::{NaiveTime, Timelike};
896 ///
897 /// let dt = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
898 /// assert_eq!(dt.with_hour(7), Some(NaiveTime::from_hms_nano(7, 56, 4, 12_345_678)));
899 /// assert_eq!(dt.with_hour(24), None);
900 /// ~~~~
901 #[inline]
with_hour(&self, hour: u32) -> Option<NaiveTime>902 fn with_hour(&self, hour: u32) -> Option<NaiveTime> {
903 if hour >= 24 {
904 return None;
905 }
906 let secs = hour * 3600 + self.secs % 3600;
907 Some(NaiveTime { secs: secs, ..*self })
908 }
909
910 /// Makes a new `NaiveTime` with the minute number changed.
911 ///
912 /// Returns `None` when the resulting `NaiveTime` would be invalid.
913 ///
914 /// # Example
915 ///
916 /// ~~~~
917 /// use chrono::{NaiveTime, Timelike};
918 ///
919 /// let dt = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
920 /// assert_eq!(dt.with_minute(45), Some(NaiveTime::from_hms_nano(23, 45, 4, 12_345_678)));
921 /// assert_eq!(dt.with_minute(60), None);
922 /// ~~~~
923 #[inline]
with_minute(&self, min: u32) -> Option<NaiveTime>924 fn with_minute(&self, min: u32) -> Option<NaiveTime> {
925 if min >= 60 {
926 return None;
927 }
928 let secs = self.secs / 3600 * 3600 + min * 60 + self.secs % 60;
929 Some(NaiveTime { secs: secs, ..*self })
930 }
931
932 /// Makes a new `NaiveTime` with the second number changed.
933 ///
934 /// Returns `None` when the resulting `NaiveTime` would be invalid.
935 /// As with the [`second`](#method.second) method,
936 /// the input range is restricted to 0 through 59.
937 ///
938 /// # Example
939 ///
940 /// ~~~~
941 /// use chrono::{NaiveTime, Timelike};
942 ///
943 /// let dt = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
944 /// assert_eq!(dt.with_second(17), Some(NaiveTime::from_hms_nano(23, 56, 17, 12_345_678)));
945 /// assert_eq!(dt.with_second(60), None);
946 /// ~~~~
947 #[inline]
with_second(&self, sec: u32) -> Option<NaiveTime>948 fn with_second(&self, sec: u32) -> Option<NaiveTime> {
949 if sec >= 60 {
950 return None;
951 }
952 let secs = self.secs / 60 * 60 + sec;
953 Some(NaiveTime { secs: secs, ..*self })
954 }
955
956 /// Makes a new `NaiveTime` with nanoseconds since the whole non-leap second changed.
957 ///
958 /// Returns `None` when the resulting `NaiveTime` would be invalid.
959 /// As with the [`nanosecond`](#method.nanosecond) method,
960 /// the input range can exceed 1,000,000,000 for leap seconds.
961 ///
962 /// # Example
963 ///
964 /// ~~~~
965 /// use chrono::{NaiveTime, Timelike};
966 ///
967 /// let dt = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
968 /// assert_eq!(dt.with_nanosecond(333_333_333),
969 /// Some(NaiveTime::from_hms_nano(23, 56, 4, 333_333_333)));
970 /// assert_eq!(dt.with_nanosecond(2_000_000_000), None);
971 /// ~~~~
972 ///
973 /// Leap seconds can theoretically follow *any* whole second.
974 /// The following would be a proper leap second at the time zone offset of UTC-00:03:57
975 /// (there are several historical examples comparable to this "non-sense" offset),
976 /// and therefore is allowed.
977 ///
978 /// ~~~~
979 /// # use chrono::{NaiveTime, Timelike};
980 /// # let dt = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
981 /// assert_eq!(dt.with_nanosecond(1_333_333_333),
982 /// Some(NaiveTime::from_hms_nano(23, 56, 4, 1_333_333_333)));
983 /// ~~~~
984 #[inline]
with_nanosecond(&self, nano: u32) -> Option<NaiveTime>985 fn with_nanosecond(&self, nano: u32) -> Option<NaiveTime> {
986 if nano >= 2_000_000_000 {
987 return None;
988 }
989 Some(NaiveTime { frac: nano, ..*self })
990 }
991
992 /// Returns the number of non-leap seconds past the last midnight.
993 ///
994 /// # Example
995 ///
996 /// ~~~~
997 /// use chrono::{NaiveTime, Timelike};
998 ///
999 /// assert_eq!(NaiveTime::from_hms(1, 2, 3).num_seconds_from_midnight(),
1000 /// 3723);
1001 /// assert_eq!(NaiveTime::from_hms_nano(23, 56, 4, 12_345_678).num_seconds_from_midnight(),
1002 /// 86164);
1003 /// assert_eq!(NaiveTime::from_hms_milli(23, 59, 59, 1_000).num_seconds_from_midnight(),
1004 /// 86399);
1005 /// ~~~~
1006 #[inline]
num_seconds_from_midnight(&self) -> u321007 fn num_seconds_from_midnight(&self) -> u32 {
1008 self.secs // do not repeat the calculation!
1009 }
1010 }
1011
1012 /// `NaiveTime` can be used as a key to the hash maps (in principle).
1013 ///
1014 /// Practically this also takes account of fractional seconds, so it is not recommended.
1015 /// (For the obvious reason this also distinguishes leap seconds from non-leap seconds.)
1016 impl hash::Hash for NaiveTime {
hash<H: hash::Hasher>(&self, state: &mut H)1017 fn hash<H: hash::Hasher>(&self, state: &mut H) {
1018 self.secs.hash(state);
1019 self.frac.hash(state);
1020 }
1021 }
1022
1023 /// An addition of `Duration` to `NaiveTime` wraps around and never overflows or underflows.
1024 /// In particular the addition ignores integral number of days.
1025 ///
1026 /// As a part of Chrono's [leap second handling](#leap-second-handling),
1027 /// the addition assumes that **there is no leap second ever**,
1028 /// except when the `NaiveTime` itself represents a leap second
1029 /// in which case the assumption becomes that **there is exactly a single leap second ever**.
1030 ///
1031 /// # Example
1032 ///
1033 /// ~~~~
1034 /// # extern crate chrono; fn main() {
1035 /// use chrono::{Duration, NaiveTime};
1036 ///
1037 /// let from_hmsm = NaiveTime::from_hms_milli;
1038 ///
1039 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::zero(), from_hmsm(3, 5, 7, 0));
1040 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(1), from_hmsm(3, 5, 8, 0));
1041 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(-1), from_hmsm(3, 5, 6, 0));
1042 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(60 + 4), from_hmsm(3, 6, 11, 0));
1043 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(7*60*60 - 6*60), from_hmsm(9, 59, 7, 0));
1044 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::milliseconds(80), from_hmsm(3, 5, 7, 80));
1045 /// assert_eq!(from_hmsm(3, 5, 7, 950) + Duration::milliseconds(280), from_hmsm(3, 5, 8, 230));
1046 /// assert_eq!(from_hmsm(3, 5, 7, 950) + Duration::milliseconds(-980), from_hmsm(3, 5, 6, 970));
1047 /// # }
1048 /// ~~~~
1049 ///
1050 /// The addition wraps around.
1051 ///
1052 /// ~~~~
1053 /// # extern crate chrono; fn main() {
1054 /// # use chrono::{Duration, NaiveTime};
1055 /// # let from_hmsm = NaiveTime::from_hms_milli;
1056 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(22*60*60), from_hmsm(1, 5, 7, 0));
1057 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(-8*60*60), from_hmsm(19, 5, 7, 0));
1058 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::days(800), from_hmsm(3, 5, 7, 0));
1059 /// # }
1060 /// ~~~~
1061 ///
1062 /// Leap seconds are handled, but the addition assumes that it is the only leap second happened.
1063 ///
1064 /// ~~~~
1065 /// # extern crate chrono; fn main() {
1066 /// # use chrono::{Duration, NaiveTime};
1067 /// # let from_hmsm = NaiveTime::from_hms_milli;
1068 /// let leap = from_hmsm(3, 5, 59, 1_300);
1069 /// assert_eq!(leap + Duration::zero(), from_hmsm(3, 5, 59, 1_300));
1070 /// assert_eq!(leap + Duration::milliseconds(-500), from_hmsm(3, 5, 59, 800));
1071 /// assert_eq!(leap + Duration::milliseconds(500), from_hmsm(3, 5, 59, 1_800));
1072 /// assert_eq!(leap + Duration::milliseconds(800), from_hmsm(3, 6, 0, 100));
1073 /// assert_eq!(leap + Duration::seconds(10), from_hmsm(3, 6, 9, 300));
1074 /// assert_eq!(leap + Duration::seconds(-10), from_hmsm(3, 5, 50, 300));
1075 /// assert_eq!(leap + Duration::days(1), from_hmsm(3, 5, 59, 300));
1076 /// # }
1077 /// ~~~~
1078 impl Add<OldDuration> for NaiveTime {
1079 type Output = NaiveTime;
1080
1081 #[inline]
add(self, rhs: OldDuration) -> NaiveTime1082 fn add(self, rhs: OldDuration) -> NaiveTime {
1083 self.overflowing_add_signed(rhs).0
1084 }
1085 }
1086
1087 impl AddAssign<OldDuration> for NaiveTime {
1088 #[inline]
add_assign(&mut self, rhs: OldDuration)1089 fn add_assign(&mut self, rhs: OldDuration) {
1090 *self = self.add(rhs);
1091 }
1092 }
1093
1094 /// A subtraction of `Duration` from `NaiveTime` wraps around and never overflows or underflows.
1095 /// In particular the addition ignores integral number of days.
1096 /// It is the same as the addition with a negated `Duration`.
1097 ///
1098 /// As a part of Chrono's [leap second handling](#leap-second-handling),
1099 /// the addition assumes that **there is no leap second ever**,
1100 /// except when the `NaiveTime` itself represents a leap second
1101 /// in which case the assumption becomes that **there is exactly a single leap second ever**.
1102 ///
1103 /// # Example
1104 ///
1105 /// ~~~~
1106 /// # extern crate chrono; fn main() {
1107 /// use chrono::{Duration, NaiveTime};
1108 ///
1109 /// let from_hmsm = NaiveTime::from_hms_milli;
1110 ///
1111 /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::zero(), from_hmsm(3, 5, 7, 0));
1112 /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::seconds(1), from_hmsm(3, 5, 6, 0));
1113 /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::seconds(60 + 5), from_hmsm(3, 4, 2, 0));
1114 /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::seconds(2*60*60 + 6*60), from_hmsm(0, 59, 7, 0));
1115 /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::milliseconds(80), from_hmsm(3, 5, 6, 920));
1116 /// assert_eq!(from_hmsm(3, 5, 7, 950) - Duration::milliseconds(280), from_hmsm(3, 5, 7, 670));
1117 /// # }
1118 /// ~~~~
1119 ///
1120 /// The subtraction wraps around.
1121 ///
1122 /// ~~~~
1123 /// # extern crate chrono; fn main() {
1124 /// # use chrono::{Duration, NaiveTime};
1125 /// # let from_hmsm = NaiveTime::from_hms_milli;
1126 /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::seconds(8*60*60), from_hmsm(19, 5, 7, 0));
1127 /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::days(800), from_hmsm(3, 5, 7, 0));
1128 /// # }
1129 /// ~~~~
1130 ///
1131 /// Leap seconds are handled, but the subtraction assumes that it is the only leap second happened.
1132 ///
1133 /// ~~~~
1134 /// # extern crate chrono; fn main() {
1135 /// # use chrono::{Duration, NaiveTime};
1136 /// # let from_hmsm = NaiveTime::from_hms_milli;
1137 /// let leap = from_hmsm(3, 5, 59, 1_300);
1138 /// assert_eq!(leap - Duration::zero(), from_hmsm(3, 5, 59, 1_300));
1139 /// assert_eq!(leap - Duration::milliseconds(200), from_hmsm(3, 5, 59, 1_100));
1140 /// assert_eq!(leap - Duration::milliseconds(500), from_hmsm(3, 5, 59, 800));
1141 /// assert_eq!(leap - Duration::seconds(60), from_hmsm(3, 5, 0, 300));
1142 /// assert_eq!(leap - Duration::days(1), from_hmsm(3, 6, 0, 300));
1143 /// # }
1144 /// ~~~~
1145 impl Sub<OldDuration> for NaiveTime {
1146 type Output = NaiveTime;
1147
1148 #[inline]
sub(self, rhs: OldDuration) -> NaiveTime1149 fn sub(self, rhs: OldDuration) -> NaiveTime {
1150 self.overflowing_sub_signed(rhs).0
1151 }
1152 }
1153
1154 impl SubAssign<OldDuration> for NaiveTime {
1155 #[inline]
sub_assign(&mut self, rhs: OldDuration)1156 fn sub_assign(&mut self, rhs: OldDuration) {
1157 *self = self.sub(rhs);
1158 }
1159 }
1160
1161 /// Subtracts another `NaiveTime` from the current time.
1162 /// Returns a `Duration` within +/- 1 day.
1163 /// This does not overflow or underflow at all.
1164 ///
1165 /// As a part of Chrono's [leap second handling](#leap-second-handling),
1166 /// the subtraction assumes that **there is no leap second ever**,
1167 /// except when any of the `NaiveTime`s themselves represents a leap second
1168 /// in which case the assumption becomes that
1169 /// **there are exactly one (or two) leap second(s) ever**.
1170 ///
1171 /// The implementation is a wrapper around
1172 /// [`NaiveTime::signed_duration_since`](#method.signed_duration_since).
1173 ///
1174 /// # Example
1175 ///
1176 /// ~~~~
1177 /// # extern crate chrono; fn main() {
1178 /// use chrono::{Duration, NaiveTime};
1179 ///
1180 /// let from_hmsm = NaiveTime::from_hms_milli;
1181 ///
1182 /// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(3, 5, 7, 900), Duration::zero());
1183 /// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(3, 5, 7, 875), Duration::milliseconds(25));
1184 /// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(3, 5, 6, 925), Duration::milliseconds(975));
1185 /// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(3, 5, 0, 900), Duration::seconds(7));
1186 /// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(3, 0, 7, 900), Duration::seconds(5 * 60));
1187 /// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(0, 5, 7, 900), Duration::seconds(3 * 3600));
1188 /// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(4, 5, 7, 900), Duration::seconds(-3600));
1189 /// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(2, 4, 6, 800),
1190 /// Duration::seconds(3600 + 60 + 1) + Duration::milliseconds(100));
1191 /// # }
1192 /// ~~~~
1193 ///
1194 /// Leap seconds are handled, but the subtraction assumes that
1195 /// there were no other leap seconds happened.
1196 ///
1197 /// ~~~~
1198 /// # extern crate chrono; fn main() {
1199 /// # use chrono::{Duration, NaiveTime};
1200 /// # let from_hmsm = NaiveTime::from_hms_milli;
1201 /// assert_eq!(from_hmsm(3, 0, 59, 1_000) - from_hmsm(3, 0, 59, 0), Duration::seconds(1));
1202 /// assert_eq!(from_hmsm(3, 0, 59, 1_500) - from_hmsm(3, 0, 59, 0),
1203 /// Duration::milliseconds(1500));
1204 /// assert_eq!(from_hmsm(3, 0, 59, 1_000) - from_hmsm(3, 0, 0, 0), Duration::seconds(60));
1205 /// assert_eq!(from_hmsm(3, 0, 0, 0) - from_hmsm(2, 59, 59, 1_000), Duration::seconds(1));
1206 /// assert_eq!(from_hmsm(3, 0, 59, 1_000) - from_hmsm(2, 59, 59, 1_000),
1207 /// Duration::seconds(61));
1208 /// # }
1209 /// ~~~~
1210 impl Sub<NaiveTime> for NaiveTime {
1211 type Output = OldDuration;
1212
1213 #[inline]
sub(self, rhs: NaiveTime) -> OldDuration1214 fn sub(self, rhs: NaiveTime) -> OldDuration {
1215 self.signed_duration_since(rhs)
1216 }
1217 }
1218
1219 /// The `Debug` output of the naive time `t` is the same as
1220 /// [`t.format("%H:%M:%S%.f")`](../format/strftime/index.html).
1221 ///
1222 /// The string printed can be readily parsed via the `parse` method on `str`.
1223 ///
1224 /// It should be noted that, for leap seconds not on the minute boundary,
1225 /// it may print a representation not distinguishable from non-leap seconds.
1226 /// This doesn't matter in practice, since such leap seconds never happened.
1227 /// (By the time of the first leap second on 1972-06-30,
1228 /// every time zone offset around the world has standardized to the 5-minute alignment.)
1229 ///
1230 /// # Example
1231 ///
1232 /// ~~~~
1233 /// use chrono::NaiveTime;
1234 ///
1235 /// assert_eq!(format!("{:?}", NaiveTime::from_hms(23, 56, 4)), "23:56:04");
1236 /// assert_eq!(format!("{:?}", NaiveTime::from_hms_milli(23, 56, 4, 12)), "23:56:04.012");
1237 /// assert_eq!(format!("{:?}", NaiveTime::from_hms_micro(23, 56, 4, 1234)), "23:56:04.001234");
1238 /// assert_eq!(format!("{:?}", NaiveTime::from_hms_nano(23, 56, 4, 123456)), "23:56:04.000123456");
1239 /// ~~~~
1240 ///
1241 /// Leap seconds may also be used.
1242 ///
1243 /// ~~~~
1244 /// # use chrono::NaiveTime;
1245 /// assert_eq!(format!("{:?}", NaiveTime::from_hms_milli(6, 59, 59, 1_500)), "06:59:60.500");
1246 /// ~~~~
1247 impl fmt::Debug for NaiveTime {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1248 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1249 let (hour, min, sec) = self.hms();
1250 let (sec, nano) = if self.frac >= 1_000_000_000 {
1251 (sec + 1, self.frac - 1_000_000_000)
1252 } else {
1253 (sec, self.frac)
1254 };
1255
1256 write!(f, "{:02}:{:02}:{:02}", hour, min, sec)?;
1257 if nano == 0 {
1258 Ok(())
1259 } else if nano % 1_000_000 == 0 {
1260 write!(f, ".{:03}", nano / 1_000_000)
1261 } else if nano % 1_000 == 0 {
1262 write!(f, ".{:06}", nano / 1_000)
1263 } else {
1264 write!(f, ".{:09}", nano)
1265 }
1266 }
1267 }
1268
1269 /// The `Display` output of the naive time `t` is the same as
1270 /// [`t.format("%H:%M:%S%.f")`](../format/strftime/index.html).
1271 ///
1272 /// The string printed can be readily parsed via the `parse` method on `str`.
1273 ///
1274 /// It should be noted that, for leap seconds not on the minute boundary,
1275 /// it may print a representation not distinguishable from non-leap seconds.
1276 /// This doesn't matter in practice, since such leap seconds never happened.
1277 /// (By the time of the first leap second on 1972-06-30,
1278 /// every time zone offset around the world has standardized to the 5-minute alignment.)
1279 ///
1280 /// # Example
1281 ///
1282 /// ~~~~
1283 /// use chrono::NaiveTime;
1284 ///
1285 /// assert_eq!(format!("{}", NaiveTime::from_hms(23, 56, 4)), "23:56:04");
1286 /// assert_eq!(format!("{}", NaiveTime::from_hms_milli(23, 56, 4, 12)), "23:56:04.012");
1287 /// assert_eq!(format!("{}", NaiveTime::from_hms_micro(23, 56, 4, 1234)), "23:56:04.001234");
1288 /// assert_eq!(format!("{}", NaiveTime::from_hms_nano(23, 56, 4, 123456)), "23:56:04.000123456");
1289 /// ~~~~
1290 ///
1291 /// Leap seconds may also be used.
1292 ///
1293 /// ~~~~
1294 /// # use chrono::NaiveTime;
1295 /// assert_eq!(format!("{}", NaiveTime::from_hms_milli(6, 59, 59, 1_500)), "06:59:60.500");
1296 /// ~~~~
1297 impl fmt::Display for NaiveTime {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1298 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1299 fmt::Debug::fmt(self, f)
1300 }
1301 }
1302
1303 /// Parsing a `str` into a `NaiveTime` uses the same format,
1304 /// [`%H:%M:%S%.f`](../format/strftime/index.html), as in `Debug` and `Display`.
1305 ///
1306 /// # Example
1307 ///
1308 /// ~~~~
1309 /// use chrono::NaiveTime;
1310 ///
1311 /// let t = NaiveTime::from_hms(23, 56, 4);
1312 /// assert_eq!("23:56:04".parse::<NaiveTime>(), Ok(t));
1313 ///
1314 /// let t = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
1315 /// assert_eq!("23:56:4.012345678".parse::<NaiveTime>(), Ok(t));
1316 ///
1317 /// let t = NaiveTime::from_hms_nano(23, 59, 59, 1_234_567_890); // leap second
1318 /// assert_eq!("23:59:60.23456789".parse::<NaiveTime>(), Ok(t));
1319 ///
1320 /// assert!("foo".parse::<NaiveTime>().is_err());
1321 /// ~~~~
1322 impl str::FromStr for NaiveTime {
1323 type Err = ParseError;
1324
from_str(s: &str) -> ParseResult<NaiveTime>1325 fn from_str(s: &str) -> ParseResult<NaiveTime> {
1326 const ITEMS: &'static [Item<'static>] = &[
1327 Item::Numeric(Numeric::Hour, Pad::Zero),
1328 Item::Space(""),
1329 Item::Literal(":"),
1330 Item::Numeric(Numeric::Minute, Pad::Zero),
1331 Item::Space(""),
1332 Item::Literal(":"),
1333 Item::Numeric(Numeric::Second, Pad::Zero),
1334 Item::Fixed(Fixed::Nanosecond),
1335 Item::Space(""),
1336 ];
1337
1338 let mut parsed = Parsed::new();
1339 parse(&mut parsed, s, ITEMS.iter())?;
1340 parsed.to_naive_time()
1341 }
1342 }
1343
1344 #[cfg(all(test, any(feature = "rustc-serialize", feature = "serde")))]
test_encodable_json<F, E>(to_string: F) where F: Fn(&NaiveTime) -> Result<String, E>, E: ::std::fmt::Debug,1345 fn test_encodable_json<F, E>(to_string: F)
1346 where
1347 F: Fn(&NaiveTime) -> Result<String, E>,
1348 E: ::std::fmt::Debug,
1349 {
1350 assert_eq!(to_string(&NaiveTime::from_hms(0, 0, 0)).ok(), Some(r#""00:00:00""#.into()));
1351 assert_eq!(
1352 to_string(&NaiveTime::from_hms_milli(0, 0, 0, 950)).ok(),
1353 Some(r#""00:00:00.950""#.into())
1354 );
1355 assert_eq!(
1356 to_string(&NaiveTime::from_hms_milli(0, 0, 59, 1_000)).ok(),
1357 Some(r#""00:00:60""#.into())
1358 );
1359 assert_eq!(to_string(&NaiveTime::from_hms(0, 1, 2)).ok(), Some(r#""00:01:02""#.into()));
1360 assert_eq!(
1361 to_string(&NaiveTime::from_hms_nano(3, 5, 7, 98765432)).ok(),
1362 Some(r#""03:05:07.098765432""#.into())
1363 );
1364 assert_eq!(to_string(&NaiveTime::from_hms(7, 8, 9)).ok(), Some(r#""07:08:09""#.into()));
1365 assert_eq!(
1366 to_string(&NaiveTime::from_hms_micro(12, 34, 56, 789)).ok(),
1367 Some(r#""12:34:56.000789""#.into())
1368 );
1369 assert_eq!(
1370 to_string(&NaiveTime::from_hms_nano(23, 59, 59, 1_999_999_999)).ok(),
1371 Some(r#""23:59:60.999999999""#.into())
1372 );
1373 }
1374
1375 #[cfg(all(test, any(feature = "rustc-serialize", feature = "serde")))]
test_decodable_json<F, E>(from_str: F) where F: Fn(&str) -> Result<NaiveTime, E>, E: ::std::fmt::Debug,1376 fn test_decodable_json<F, E>(from_str: F)
1377 where
1378 F: Fn(&str) -> Result<NaiveTime, E>,
1379 E: ::std::fmt::Debug,
1380 {
1381 assert_eq!(from_str(r#""00:00:00""#).ok(), Some(NaiveTime::from_hms(0, 0, 0)));
1382 assert_eq!(from_str(r#""0:0:0""#).ok(), Some(NaiveTime::from_hms(0, 0, 0)));
1383 assert_eq!(from_str(r#""00:00:00.950""#).ok(), Some(NaiveTime::from_hms_milli(0, 0, 0, 950)));
1384 assert_eq!(from_str(r#""0:0:0.95""#).ok(), Some(NaiveTime::from_hms_milli(0, 0, 0, 950)));
1385 assert_eq!(from_str(r#""00:00:60""#).ok(), Some(NaiveTime::from_hms_milli(0, 0, 59, 1_000)));
1386 assert_eq!(from_str(r#""00:01:02""#).ok(), Some(NaiveTime::from_hms(0, 1, 2)));
1387 assert_eq!(
1388 from_str(r#""03:05:07.098765432""#).ok(),
1389 Some(NaiveTime::from_hms_nano(3, 5, 7, 98765432))
1390 );
1391 assert_eq!(from_str(r#""07:08:09""#).ok(), Some(NaiveTime::from_hms(7, 8, 9)));
1392 assert_eq!(
1393 from_str(r#""12:34:56.000789""#).ok(),
1394 Some(NaiveTime::from_hms_micro(12, 34, 56, 789))
1395 );
1396 assert_eq!(
1397 from_str(r#""23:59:60.999999999""#).ok(),
1398 Some(NaiveTime::from_hms_nano(23, 59, 59, 1_999_999_999))
1399 );
1400 assert_eq!(
1401 from_str(r#""23:59:60.9999999999997""#).ok(), // excess digits are ignored
1402 Some(NaiveTime::from_hms_nano(23, 59, 59, 1_999_999_999))
1403 );
1404
1405 // bad formats
1406 assert!(from_str(r#""""#).is_err());
1407 assert!(from_str(r#""000000""#).is_err());
1408 assert!(from_str(r#""00:00:61""#).is_err());
1409 assert!(from_str(r#""00:60:00""#).is_err());
1410 assert!(from_str(r#""24:00:00""#).is_err());
1411 assert!(from_str(r#""23:59:59,1""#).is_err());
1412 assert!(from_str(r#""012:34:56""#).is_err());
1413 assert!(from_str(r#""hh:mm:ss""#).is_err());
1414 assert!(from_str(r#"0"#).is_err());
1415 assert!(from_str(r#"86399"#).is_err());
1416 assert!(from_str(r#"{}"#).is_err());
1417 // pre-0.3.0 rustc-serialize format is now invalid
1418 assert!(from_str(r#"{"secs":0,"frac":0}"#).is_err());
1419 assert!(from_str(r#"null"#).is_err());
1420 }
1421
1422 #[cfg(feature = "rustc-serialize")]
1423 mod rustc_serialize {
1424 use super::NaiveTime;
1425 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
1426
1427 impl Encodable for NaiveTime {
encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error>1428 fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
1429 format!("{:?}", self).encode(s)
1430 }
1431 }
1432
1433 impl Decodable for NaiveTime {
decode<D: Decoder>(d: &mut D) -> Result<NaiveTime, D::Error>1434 fn decode<D: Decoder>(d: &mut D) -> Result<NaiveTime, D::Error> {
1435 d.read_str()?.parse().map_err(|_| d.error("invalid time"))
1436 }
1437 }
1438
1439 #[cfg(test)]
1440 use rustc_serialize::json;
1441
1442 #[test]
test_encodable()1443 fn test_encodable() {
1444 super::test_encodable_json(json::encode);
1445 }
1446
1447 #[test]
test_decodable()1448 fn test_decodable() {
1449 super::test_decodable_json(json::decode);
1450 }
1451 }
1452
1453 #[cfg(feature = "serde")]
1454 mod serde {
1455 use super::NaiveTime;
1456 use core::fmt;
1457 use serdelib::{de, ser};
1458
1459 // TODO not very optimized for space (binary formats would want something better)
1460 // TODO round-trip for general leap seconds (not just those with second = 60)
1461
1462 impl ser::Serialize for NaiveTime {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,1463 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1464 where
1465 S: ser::Serializer,
1466 {
1467 serializer.collect_str(&self)
1468 }
1469 }
1470
1471 struct NaiveTimeVisitor;
1472
1473 impl<'de> de::Visitor<'de> for NaiveTimeVisitor {
1474 type Value = NaiveTime;
1475
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result1476 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1477 write!(formatter, "a formatted time string")
1478 }
1479
visit_str<E>(self, value: &str) -> Result<NaiveTime, E> where E: de::Error,1480 fn visit_str<E>(self, value: &str) -> Result<NaiveTime, E>
1481 where
1482 E: de::Error,
1483 {
1484 value.parse().map_err(E::custom)
1485 }
1486 }
1487
1488 impl<'de> de::Deserialize<'de> for NaiveTime {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: de::Deserializer<'de>,1489 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1490 where
1491 D: de::Deserializer<'de>,
1492 {
1493 deserializer.deserialize_str(NaiveTimeVisitor)
1494 }
1495 }
1496
1497 #[cfg(test)]
1498 extern crate bincode;
1499 #[cfg(test)]
1500 extern crate serde_json;
1501
1502 #[test]
test_serde_serialize()1503 fn test_serde_serialize() {
1504 super::test_encodable_json(self::serde_json::to_string);
1505 }
1506
1507 #[test]
test_serde_deserialize()1508 fn test_serde_deserialize() {
1509 super::test_decodable_json(|input| self::serde_json::from_str(&input));
1510 }
1511
1512 #[test]
test_serde_bincode()1513 fn test_serde_bincode() {
1514 // Bincode is relevant to test separately from JSON because
1515 // it is not self-describing.
1516 use self::bincode::{deserialize, serialize, Infinite};
1517
1518 let t = NaiveTime::from_hms_nano(3, 5, 7, 98765432);
1519 let encoded = serialize(&t, Infinite).unwrap();
1520 let decoded: NaiveTime = deserialize(&encoded).unwrap();
1521 assert_eq!(t, decoded);
1522 }
1523 }
1524
1525 #[cfg(test)]
1526 mod tests {
1527 use super::NaiveTime;
1528 use oldtime::Duration;
1529 use std::u32;
1530 use Timelike;
1531
1532 #[test]
test_time_from_hms_milli()1533 fn test_time_from_hms_milli() {
1534 assert_eq!(
1535 NaiveTime::from_hms_milli_opt(3, 5, 7, 0),
1536 Some(NaiveTime::from_hms_nano(3, 5, 7, 0))
1537 );
1538 assert_eq!(
1539 NaiveTime::from_hms_milli_opt(3, 5, 7, 777),
1540 Some(NaiveTime::from_hms_nano(3, 5, 7, 777_000_000))
1541 );
1542 assert_eq!(
1543 NaiveTime::from_hms_milli_opt(3, 5, 7, 1_999),
1544 Some(NaiveTime::from_hms_nano(3, 5, 7, 1_999_000_000))
1545 );
1546 assert_eq!(NaiveTime::from_hms_milli_opt(3, 5, 7, 2_000), None);
1547 assert_eq!(NaiveTime::from_hms_milli_opt(3, 5, 7, 5_000), None); // overflow check
1548 assert_eq!(NaiveTime::from_hms_milli_opt(3, 5, 7, u32::MAX), None);
1549 }
1550
1551 #[test]
test_time_from_hms_micro()1552 fn test_time_from_hms_micro() {
1553 assert_eq!(
1554 NaiveTime::from_hms_micro_opt(3, 5, 7, 0),
1555 Some(NaiveTime::from_hms_nano(3, 5, 7, 0))
1556 );
1557 assert_eq!(
1558 NaiveTime::from_hms_micro_opt(3, 5, 7, 333),
1559 Some(NaiveTime::from_hms_nano(3, 5, 7, 333_000))
1560 );
1561 assert_eq!(
1562 NaiveTime::from_hms_micro_opt(3, 5, 7, 777_777),
1563 Some(NaiveTime::from_hms_nano(3, 5, 7, 777_777_000))
1564 );
1565 assert_eq!(
1566 NaiveTime::from_hms_micro_opt(3, 5, 7, 1_999_999),
1567 Some(NaiveTime::from_hms_nano(3, 5, 7, 1_999_999_000))
1568 );
1569 assert_eq!(NaiveTime::from_hms_micro_opt(3, 5, 7, 2_000_000), None);
1570 assert_eq!(NaiveTime::from_hms_micro_opt(3, 5, 7, 5_000_000), None); // overflow check
1571 assert_eq!(NaiveTime::from_hms_micro_opt(3, 5, 7, u32::MAX), None);
1572 }
1573
1574 #[test]
test_time_hms()1575 fn test_time_hms() {
1576 assert_eq!(NaiveTime::from_hms(3, 5, 7).hour(), 3);
1577 assert_eq!(NaiveTime::from_hms(3, 5, 7).with_hour(0), Some(NaiveTime::from_hms(0, 5, 7)));
1578 assert_eq!(NaiveTime::from_hms(3, 5, 7).with_hour(23), Some(NaiveTime::from_hms(23, 5, 7)));
1579 assert_eq!(NaiveTime::from_hms(3, 5, 7).with_hour(24), None);
1580 assert_eq!(NaiveTime::from_hms(3, 5, 7).with_hour(u32::MAX), None);
1581
1582 assert_eq!(NaiveTime::from_hms(3, 5, 7).minute(), 5);
1583 assert_eq!(NaiveTime::from_hms(3, 5, 7).with_minute(0), Some(NaiveTime::from_hms(3, 0, 7)));
1584 assert_eq!(
1585 NaiveTime::from_hms(3, 5, 7).with_minute(59),
1586 Some(NaiveTime::from_hms(3, 59, 7))
1587 );
1588 assert_eq!(NaiveTime::from_hms(3, 5, 7).with_minute(60), None);
1589 assert_eq!(NaiveTime::from_hms(3, 5, 7).with_minute(u32::MAX), None);
1590
1591 assert_eq!(NaiveTime::from_hms(3, 5, 7).second(), 7);
1592 assert_eq!(NaiveTime::from_hms(3, 5, 7).with_second(0), Some(NaiveTime::from_hms(3, 5, 0)));
1593 assert_eq!(
1594 NaiveTime::from_hms(3, 5, 7).with_second(59),
1595 Some(NaiveTime::from_hms(3, 5, 59))
1596 );
1597 assert_eq!(NaiveTime::from_hms(3, 5, 7).with_second(60), None);
1598 assert_eq!(NaiveTime::from_hms(3, 5, 7).with_second(u32::MAX), None);
1599 }
1600
1601 #[test]
test_time_add()1602 fn test_time_add() {
1603 macro_rules! check {
1604 ($lhs:expr, $rhs:expr, $sum:expr) => {{
1605 assert_eq!($lhs + $rhs, $sum);
1606 //assert_eq!($rhs + $lhs, $sum);
1607 }};
1608 }
1609
1610 let hmsm = |h, m, s, mi| NaiveTime::from_hms_milli(h, m, s, mi);
1611
1612 check!(hmsm(3, 5, 7, 900), Duration::zero(), hmsm(3, 5, 7, 900));
1613 check!(hmsm(3, 5, 7, 900), Duration::milliseconds(100), hmsm(3, 5, 8, 0));
1614 check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(-1800), hmsm(3, 5, 6, 500));
1615 check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(-800), hmsm(3, 5, 7, 500));
1616 check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(-100), hmsm(3, 5, 7, 1_200));
1617 check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(100), hmsm(3, 5, 7, 1_400));
1618 check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(800), hmsm(3, 5, 8, 100));
1619 check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(1800), hmsm(3, 5, 9, 100));
1620 check!(hmsm(3, 5, 7, 900), Duration::seconds(86399), hmsm(3, 5, 6, 900)); // overwrap
1621 check!(hmsm(3, 5, 7, 900), Duration::seconds(-86399), hmsm(3, 5, 8, 900));
1622 check!(hmsm(3, 5, 7, 900), Duration::days(12345), hmsm(3, 5, 7, 900));
1623 check!(hmsm(3, 5, 7, 1_300), Duration::days(1), hmsm(3, 5, 7, 300));
1624 check!(hmsm(3, 5, 7, 1_300), Duration::days(-1), hmsm(3, 5, 8, 300));
1625
1626 // regression tests for #37
1627 check!(hmsm(0, 0, 0, 0), Duration::milliseconds(-990), hmsm(23, 59, 59, 10));
1628 check!(hmsm(0, 0, 0, 0), Duration::milliseconds(-9990), hmsm(23, 59, 50, 10));
1629 }
1630
1631 #[test]
test_time_overflowing_add()1632 fn test_time_overflowing_add() {
1633 let hmsm = NaiveTime::from_hms_milli;
1634
1635 assert_eq!(
1636 hmsm(3, 4, 5, 678).overflowing_add_signed(Duration::hours(11)),
1637 (hmsm(14, 4, 5, 678), 0)
1638 );
1639 assert_eq!(
1640 hmsm(3, 4, 5, 678).overflowing_add_signed(Duration::hours(23)),
1641 (hmsm(2, 4, 5, 678), 86_400)
1642 );
1643 assert_eq!(
1644 hmsm(3, 4, 5, 678).overflowing_add_signed(Duration::hours(-7)),
1645 (hmsm(20, 4, 5, 678), -86_400)
1646 );
1647
1648 // overflowing_add_signed with leap seconds may be counter-intuitive
1649 assert_eq!(
1650 hmsm(3, 4, 5, 1_678).overflowing_add_signed(Duration::days(1)),
1651 (hmsm(3, 4, 5, 678), 86_400)
1652 );
1653 assert_eq!(
1654 hmsm(3, 4, 5, 1_678).overflowing_add_signed(Duration::days(-1)),
1655 (hmsm(3, 4, 6, 678), -86_400)
1656 );
1657 }
1658
1659 #[test]
test_time_addassignment()1660 fn test_time_addassignment() {
1661 let hms = NaiveTime::from_hms;
1662 let mut time = hms(12, 12, 12);
1663 time += Duration::hours(10);
1664 assert_eq!(time, hms(22, 12, 12));
1665 time += Duration::hours(10);
1666 assert_eq!(time, hms(8, 12, 12));
1667 }
1668
1669 #[test]
test_time_subassignment()1670 fn test_time_subassignment() {
1671 let hms = NaiveTime::from_hms;
1672 let mut time = hms(12, 12, 12);
1673 time -= Duration::hours(10);
1674 assert_eq!(time, hms(2, 12, 12));
1675 time -= Duration::hours(10);
1676 assert_eq!(time, hms(16, 12, 12));
1677 }
1678
1679 #[test]
test_time_sub()1680 fn test_time_sub() {
1681 macro_rules! check {
1682 ($lhs:expr, $rhs:expr, $diff:expr) => {{
1683 // `time1 - time2 = duration` is equivalent to `time2 - time1 = -duration`
1684 assert_eq!($lhs.signed_duration_since($rhs), $diff);
1685 assert_eq!($rhs.signed_duration_since($lhs), -$diff);
1686 }};
1687 }
1688
1689 let hmsm = |h, m, s, mi| NaiveTime::from_hms_milli(h, m, s, mi);
1690
1691 check!(hmsm(3, 5, 7, 900), hmsm(3, 5, 7, 900), Duration::zero());
1692 check!(hmsm(3, 5, 7, 900), hmsm(3, 5, 7, 600), Duration::milliseconds(300));
1693 check!(hmsm(3, 5, 7, 200), hmsm(2, 4, 6, 200), Duration::seconds(3600 + 60 + 1));
1694 check!(
1695 hmsm(3, 5, 7, 200),
1696 hmsm(2, 4, 6, 300),
1697 Duration::seconds(3600 + 60) + Duration::milliseconds(900)
1698 );
1699
1700 // treats the leap second as if it coincides with the prior non-leap second,
1701 // as required by `time1 - time2 = duration` and `time2 - time1 = -duration` equivalence.
1702 check!(hmsm(3, 5, 7, 200), hmsm(3, 5, 6, 1_800), Duration::milliseconds(400));
1703 check!(hmsm(3, 5, 7, 1_200), hmsm(3, 5, 6, 1_800), Duration::milliseconds(1400));
1704 check!(hmsm(3, 5, 7, 1_200), hmsm(3, 5, 6, 800), Duration::milliseconds(1400));
1705
1706 // additional equality: `time1 + duration = time2` is equivalent to
1707 // `time2 - time1 = duration` IF AND ONLY IF `time2` represents a non-leap second.
1708 assert_eq!(hmsm(3, 5, 6, 800) + Duration::milliseconds(400), hmsm(3, 5, 7, 200));
1709 assert_eq!(hmsm(3, 5, 6, 1_800) + Duration::milliseconds(400), hmsm(3, 5, 7, 200));
1710 }
1711
1712 #[test]
test_time_fmt()1713 fn test_time_fmt() {
1714 assert_eq!(format!("{}", NaiveTime::from_hms_milli(23, 59, 59, 999)), "23:59:59.999");
1715 assert_eq!(format!("{}", NaiveTime::from_hms_milli(23, 59, 59, 1_000)), "23:59:60");
1716 assert_eq!(format!("{}", NaiveTime::from_hms_milli(23, 59, 59, 1_001)), "23:59:60.001");
1717 assert_eq!(format!("{}", NaiveTime::from_hms_micro(0, 0, 0, 43210)), "00:00:00.043210");
1718 assert_eq!(format!("{}", NaiveTime::from_hms_nano(0, 0, 0, 6543210)), "00:00:00.006543210");
1719
1720 // the format specifier should have no effect on `NaiveTime`
1721 assert_eq!(format!("{:30}", NaiveTime::from_hms_milli(3, 5, 7, 9)), "03:05:07.009");
1722 }
1723
1724 #[test]
test_date_from_str()1725 fn test_date_from_str() {
1726 // valid cases
1727 let valid = [
1728 "0:0:0",
1729 "0:0:0.0000000",
1730 "0:0:0.0000003",
1731 " 4 : 3 : 2.1 ",
1732 " 09:08:07 ",
1733 " 9:8:07 ",
1734 "23:59:60.373929310237",
1735 ];
1736 for &s in &valid {
1737 let d = match s.parse::<NaiveTime>() {
1738 Ok(d) => d,
1739 Err(e) => panic!("parsing `{}` has failed: {}", s, e),
1740 };
1741 let s_ = format!("{:?}", d);
1742 // `s` and `s_` may differ, but `s.parse()` and `s_.parse()` must be same
1743 let d_ = match s_.parse::<NaiveTime>() {
1744 Ok(d) => d,
1745 Err(e) => {
1746 panic!("`{}` is parsed into `{:?}`, but reparsing that has failed: {}", s, d, e)
1747 }
1748 };
1749 assert!(
1750 d == d_,
1751 "`{}` is parsed into `{:?}`, but reparsed result \
1752 `{:?}` does not match",
1753 s,
1754 d,
1755 d_
1756 );
1757 }
1758
1759 // some invalid cases
1760 // since `ParseErrorKind` is private, all we can do is to check if there was an error
1761 assert!("".parse::<NaiveTime>().is_err());
1762 assert!("x".parse::<NaiveTime>().is_err());
1763 assert!("15".parse::<NaiveTime>().is_err());
1764 assert!("15:8".parse::<NaiveTime>().is_err());
1765 assert!("15:8:x".parse::<NaiveTime>().is_err());
1766 assert!("15:8:9x".parse::<NaiveTime>().is_err());
1767 assert!("23:59:61".parse::<NaiveTime>().is_err());
1768 assert!("12:34:56.x".parse::<NaiveTime>().is_err());
1769 assert!("12:34:56. 0".parse::<NaiveTime>().is_err());
1770 }
1771
1772 #[test]
test_time_parse_from_str()1773 fn test_time_parse_from_str() {
1774 let hms = |h, m, s| NaiveTime::from_hms(h, m, s);
1775 assert_eq!(
1776 NaiveTime::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
1777 Ok(hms(12, 34, 56))
1778 ); // ignore date and offset
1779 assert_eq!(NaiveTime::parse_from_str("PM 12:59", "%P %H:%M"), Ok(hms(12, 59, 0)));
1780 assert!(NaiveTime::parse_from_str("12:3456", "%H:%M:%S").is_err());
1781 }
1782
1783 #[test]
test_time_format()1784 fn test_time_format() {
1785 let t = NaiveTime::from_hms_nano(3, 5, 7, 98765432);
1786 assert_eq!(t.format("%H,%k,%I,%l,%P,%p").to_string(), "03, 3,03, 3,am,AM");
1787 assert_eq!(t.format("%M").to_string(), "05");
1788 assert_eq!(t.format("%S,%f,%.f").to_string(), "07,098765432,.098765432");
1789 assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".098,.098765,.098765432");
1790 assert_eq!(t.format("%R").to_string(), "03:05");
1791 assert_eq!(t.format("%T,%X").to_string(), "03:05:07,03:05:07");
1792 assert_eq!(t.format("%r").to_string(), "03:05:07 AM");
1793 assert_eq!(t.format("%t%n%%%n%t").to_string(), "\t\n%\n\t");
1794
1795 let t = NaiveTime::from_hms_micro(3, 5, 7, 432100);
1796 assert_eq!(t.format("%S,%f,%.f").to_string(), "07,432100000,.432100");
1797 assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".432,.432100,.432100000");
1798
1799 let t = NaiveTime::from_hms_milli(3, 5, 7, 210);
1800 assert_eq!(t.format("%S,%f,%.f").to_string(), "07,210000000,.210");
1801 assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".210,.210000,.210000000");
1802
1803 let t = NaiveTime::from_hms(3, 5, 7);
1804 assert_eq!(t.format("%S,%f,%.f").to_string(), "07,000000000,");
1805 assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".000,.000000,.000000000");
1806
1807 // corner cases
1808 assert_eq!(NaiveTime::from_hms(13, 57, 9).format("%r").to_string(), "01:57:09 PM");
1809 assert_eq!(
1810 NaiveTime::from_hms_milli(23, 59, 59, 1_000).format("%X").to_string(),
1811 "23:59:60"
1812 );
1813 }
1814 }
1815