1 // This is a part of Chrono.
2 // See README.md and LICENSE.txt for details.
4 //! ISO 8601 time without timezone.
6 use std
::{str, fmt, hash}
;
7 use std
::ops
::{Add, Sub, AddAssign, SubAssign}
;
8 use oldtime
::Duration
as OldDuration
;
11 use div
::div_mod_floor
;
12 use format
::{Item, Numeric, Pad, Fixed}
;
13 use format
::{parse, Parsed, ParseError, ParseResult, DelayedFormat, StrftimeItems}
;
15 /// ISO 8601 time without timezone.
16 /// Allows for the nanosecond precision and optional leap second representation.
18 /// # Leap Second Handling
20 /// Since 1960s, the manmade atomic clock has been so accurate that
21 /// it is much more accurate than Earth's own motion.
22 /// It became desirable to define the civil time in terms of the atomic clock,
23 /// but that risks the desynchronization of the civil time from Earth.
24 /// To account for this, the designers of the Coordinated Universal Time (UTC)
25 /// made that the UTC should be kept within 0.9 seconds of the observed Earth-bound time.
26 /// When the mean solar day is longer than the ideal (86,400 seconds),
27 /// the error slowly accumulates and it is necessary to add a **leap second**
28 /// to slow the UTC down a bit.
29 /// (We may also remove a second to speed the UTC up a bit, but it never happened.)
30 /// The leap second, if any, follows 23:59:59 of June 30 or December 31 in the UTC.
32 /// Fast forward to the 21st century,
33 /// we have seen 26 leap seconds from January 1972 to December 2015.
34 /// Yes, 26 seconds. Probably you can read this paragraph within 26 seconds.
35 /// But those 26 seconds, and possibly more in the future, are never predictable,
36 /// and whether to add a leap second or not is known only before 6 months.
37 /// Internet-based clocks (via NTP) do account for known leap seconds,
38 /// but the system API normally doesn't (and often can't, with no network connection)
39 /// and there is no reliable way to retrieve leap second information.
41 /// Chrono does not try to accurately implement leap seconds; it is impossible.
42 /// Rather, **it allows for leap seconds but behaves as if there are *no other* leap seconds.**
43 /// Various operations will ignore any possible leap second(s)
44 /// except when any of the operands were actually leap seconds.
46 /// If you cannot tolerate this behavior,
47 /// you must use a separate `TimeZone` for the International Atomic Time (TAI).
48 /// TAI is like UTC but has no leap seconds, and thus slightly differs from UTC.
49 /// Chrono does not yet provide such implementation, but it is planned.
51 /// ## Representing Leap Seconds
53 /// The leap second is indicated via fractional seconds more than 1 second.
54 /// This makes possible to treat a leap second as the prior non-leap second
55 /// if you don't care about sub-second accuracy.
56 /// You should use the proper formatting to get the raw leap second.
58 /// All methods accepting fractional seconds will accept such values.
61 /// use chrono::{NaiveDate, NaiveTime, Utc, TimeZone};
63 /// let t = NaiveTime::from_hms_milli(8, 59, 59, 1_000);
65 /// let dt1 = NaiveDate::from_ymd(2015, 7, 1).and_hms_micro(8, 59, 59, 1_000_000);
67 /// let dt2 = Utc.ymd(2015, 6, 30).and_hms_nano(23, 59, 59, 1_000_000_000);
68 /// # let _ = (t, dt1, dt2);
71 /// Note that the leap second can happen anytime given an appropriate time zone;
72 /// 2015-07-01 01:23:60 would be a proper leap second if UTC+01:24 had existed.
73 /// Practically speaking, though, by the time of the first leap second on 1972-06-30,
74 /// every time zone offset around the world has standardized to the 5-minute alignment.
76 /// ## Date And Time Arithmetics
78 /// As a concrete example, let's assume that `03:00:60` and `04:00:60` are leap seconds.
79 /// In reality, of course, leap seconds are separated by at least 6 months.
80 /// We will also use some intuitive concise notations for the explanation.
83 /// (short for [`NaiveTime::overflowing_add_signed`](#method.overflowing_add_signed)):
85 /// - `03:00:00 + 1s = 03:00:01`.
86 /// - `03:00:59 + 60s = 03:02:00`.
87 /// - `03:00:59 + 1s = 03:01:00`.
88 /// - `03:00:60 + 1s = 03:01:00`.
89 /// Note that the sum is identical to the previous.
90 /// - `03:00:60 + 60s = 03:01:59`.
91 /// - `03:00:60 + 61s = 03:02:00`.
92 /// - `03:00:60.1 + 0.8s = 03:00:60.9`.
95 /// (short for [`NaiveTime::overflowing_sub_signed`](#method.overflowing_sub_signed)):
97 /// - `03:00:00 - 1s = 02:59:59`.
98 /// - `03:01:00 - 1s = 03:00:59`.
99 /// - `03:01:00 - 60s = 03:00:00`.
100 /// - `03:00:60 - 60s = 03:00:00`.
101 /// Note that the result is identical to the previous.
102 /// - `03:00:60.7 - 0.4s = 03:00:60.3`.
103 /// - `03:00:60.7 - 0.9s = 03:00:59.8`.
106 /// (short for [`NaiveTime::signed_duration_since`](#method.signed_duration_since)):
108 /// - `04:00:00 - 03:00:00 = 3600s`.
109 /// - `03:01:00 - 03:00:00 = 60s`.
110 /// - `03:00:60 - 03:00:00 = 60s`.
111 /// Note that the difference is identical to the previous.
112 /// - `03:00:60.6 - 03:00:59.4 = 1.2s`.
113 /// - `03:01:00 - 03:00:59.8 = 0.2s`.
114 /// - `03:01:00 - 03:00:60.5 = 0.5s`.
115 /// Note that the difference is larger than the previous,
116 /// even though the leap second clearly follows the previous whole second.
117 /// - `04:00:60.9 - 03:00:60.1 =
118 /// (04:00:60.9 - 04:00:00) + (04:00:00 - 03:01:00) + (03:01:00 - 03:00:60.1) =
119 /// 60.9s + 3540s + 0.9s = 3601.8s`.
123 /// - `Time + Duration` unconditionally equals to `Duration + Time`.
125 /// - `Time - Duration` unconditionally equals to `Time + (-Duration)`.
127 /// - `Time1 - Time2` unconditionally equals to `-(Time2 - Time1)`.
129 /// - Associativity does not generally hold, because
130 /// `(Time + Duration1) - Duration2` no longer equals to `Time + (Duration1 - Duration2)`
131 /// for two positive durations.
133 /// - As a special case, `(Time + Duration) - Duration` also does not equal to `Time`.
135 /// - If you can assume that all durations have the same sign, however,
136 /// then the associativity holds:
137 /// `(Time + Duration1) + Duration2` equals to `Time + (Duration1 + Duration2)`
138 /// for two positive durations.
140 /// ## Reading And Writing Leap Seconds
142 /// The "typical" leap seconds on the minute boundary are
143 /// correctly handled both in the formatting and parsing.
144 /// The leap second in the human-readable representation
145 /// will be represented as the second part being 60, as required by ISO 8601.
148 /// use chrono::{Utc, TimeZone};
150 /// let dt = Utc.ymd(2015, 6, 30).and_hms_milli(23, 59, 59, 1_000);
151 /// assert_eq!(format!("{:?}", dt), "2015-06-30T23:59:60Z");
154 /// There are hypothetical leap seconds not on the minute boundary
155 /// nevertheless supported by Chrono.
156 /// They are allowed for the sake of completeness and consistency;
157 /// there were several "exotic" time zone offsets with fractional minutes prior to UTC after all.
158 /// For such cases the human-readable representation is ambiguous
159 /// and would be read back to the next non-leap second.
162 /// use chrono::{DateTime, Utc, TimeZone};
164 /// let dt = Utc.ymd(2015, 6, 30).and_hms_milli(23, 56, 4, 1_000);
165 /// assert_eq!(format!("{:?}", dt), "2015-06-30T23:56:05Z");
167 /// let dt = Utc.ymd(2015, 6, 30).and_hms(23, 56, 5);
168 /// assert_eq!(format!("{:?}", dt), "2015-06-30T23:56:05Z");
169 /// assert_eq!(DateTime::parse_from_rfc3339("2015-06-30T23:56:05Z").unwrap(), dt);
172 /// Since Chrono alone cannot determine any existence of leap seconds,
173 /// **there is absolutely no guarantee that the leap second read has actually happened**.
174 #[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
175 pub struct NaiveTime
{
181 /// Makes a new `NaiveTime` from hour, minute and second.
183 /// No [leap second](#leap-second-handling) is allowed here;
184 /// use `NaiveTime::from_hms_*` methods with a subsecond parameter instead.
186 /// Panics on invalid hour, minute and/or second.
191 /// use chrono::{NaiveTime, Timelike};
193 /// let t = NaiveTime::from_hms(23, 56, 4);
194 /// assert_eq!(t.hour(), 23);
195 /// assert_eq!(t.minute(), 56);
196 /// assert_eq!(t.second(), 4);
197 /// assert_eq!(t.nanosecond(), 0);
200 pub fn from_hms(hour
: u32, min
: u32, sec
: u32) -> NaiveTime
{
201 NaiveTime
::from_hms_opt(hour
, min
, sec
).expect("invalid time")
204 /// Makes a new `NaiveTime` from hour, minute and second.
206 /// No [leap second](#leap-second-handling) is allowed here;
207 /// use `NaiveTime::from_hms_*_opt` methods with a subsecond parameter instead.
209 /// Returns `None` on invalid hour, minute and/or second.
214 /// use chrono::NaiveTime;
216 /// let from_hms_opt = NaiveTime::from_hms_opt;
218 /// assert!(from_hms_opt(0, 0, 0).is_some());
219 /// assert!(from_hms_opt(23, 59, 59).is_some());
220 /// assert!(from_hms_opt(24, 0, 0).is_none());
221 /// assert!(from_hms_opt(23, 60, 0).is_none());
222 /// assert!(from_hms_opt(23, 59, 60).is_none());
225 pub fn from_hms_opt(hour
: u32, min
: u32, sec
: u32) -> Option
<NaiveTime
> {
226 NaiveTime
::from_hms_nano_opt(hour
, min
, sec
, 0)
229 /// Makes a new `NaiveTime` from hour, minute, second and millisecond.
231 /// The millisecond part can exceed 1,000
232 /// in order to represent the [leap second](#leap-second-handling).
234 /// Panics on invalid hour, minute, second and/or millisecond.
239 /// use chrono::{NaiveTime, Timelike};
241 /// let t = NaiveTime::from_hms_milli(23, 56, 4, 12);
242 /// assert_eq!(t.hour(), 23);
243 /// assert_eq!(t.minute(), 56);
244 /// assert_eq!(t.second(), 4);
245 /// assert_eq!(t.nanosecond(), 12_000_000);
248 pub fn from_hms_milli(hour
: u32, min
: u32, sec
: u32, milli
: u32) -> NaiveTime
{
249 NaiveTime
::from_hms_milli_opt(hour
, min
, sec
, milli
).expect("invalid time")
252 /// Makes a new `NaiveTime` from hour, minute, second and millisecond.
254 /// The millisecond part can exceed 1,000
255 /// in order to represent the [leap second](#leap-second-handling).
257 /// Returns `None` on invalid hour, minute, second and/or millisecond.
262 /// use chrono::NaiveTime;
264 /// let from_hmsm_opt = NaiveTime::from_hms_milli_opt;
266 /// assert!(from_hmsm_opt(0, 0, 0, 0).is_some());
267 /// assert!(from_hmsm_opt(23, 59, 59, 999).is_some());
268 /// assert!(from_hmsm_opt(23, 59, 59, 1_999).is_some()); // a leap second after 23:59:59
269 /// assert!(from_hmsm_opt(24, 0, 0, 0).is_none());
270 /// assert!(from_hmsm_opt(23, 60, 0, 0).is_none());
271 /// assert!(from_hmsm_opt(23, 59, 60, 0).is_none());
272 /// assert!(from_hmsm_opt(23, 59, 59, 2_000).is_none());
275 pub fn from_hms_milli_opt(hour
: u32, min
: u32, sec
: u32, milli
: u32) -> Option
<NaiveTime
> {
276 milli
.checked_mul(1_000_000)
277 .and_then(|nano
| NaiveTime
::from_hms_nano_opt(hour
, min
, sec
, nano
))
280 /// Makes a new `NaiveTime` from hour, minute, second and microsecond.
282 /// The microsecond part can exceed 1,000,000
283 /// in order to represent the [leap second](#leap-second-handling).
285 /// Panics on invalid hour, minute, second and/or microsecond.
290 /// use chrono::{NaiveTime, Timelike};
292 /// let t = NaiveTime::from_hms_micro(23, 56, 4, 12_345);
293 /// assert_eq!(t.hour(), 23);
294 /// assert_eq!(t.minute(), 56);
295 /// assert_eq!(t.second(), 4);
296 /// assert_eq!(t.nanosecond(), 12_345_000);
299 pub fn from_hms_micro(hour
: u32, min
: u32, sec
: u32, micro
: u32) -> NaiveTime
{
300 NaiveTime
::from_hms_micro_opt(hour
, min
, sec
, micro
).expect("invalid time")
303 /// Makes a new `NaiveTime` from hour, minute, second and microsecond.
305 /// The microsecond part can exceed 1,000,000
306 /// in order to represent the [leap second](#leap-second-handling).
308 /// Returns `None` on invalid hour, minute, second and/or microsecond.
313 /// use chrono::NaiveTime;
315 /// let from_hmsu_opt = NaiveTime::from_hms_micro_opt;
317 /// assert!(from_hmsu_opt(0, 0, 0, 0).is_some());
318 /// assert!(from_hmsu_opt(23, 59, 59, 999_999).is_some());
319 /// assert!(from_hmsu_opt(23, 59, 59, 1_999_999).is_some()); // a leap second after 23:59:59
320 /// assert!(from_hmsu_opt(24, 0, 0, 0).is_none());
321 /// assert!(from_hmsu_opt(23, 60, 0, 0).is_none());
322 /// assert!(from_hmsu_opt(23, 59, 60, 0).is_none());
323 /// assert!(from_hmsu_opt(23, 59, 59, 2_000_000).is_none());
326 pub fn from_hms_micro_opt(hour
: u32, min
: u32, sec
: u32, micro
: u32) -> Option
<NaiveTime
> {
327 micro
.checked_mul(1_000)
328 .and_then(|nano
| NaiveTime
::from_hms_nano_opt(hour
, min
, sec
, nano
))
331 /// Makes a new `NaiveTime` from hour, minute, second and nanosecond.
333 /// The nanosecond part can exceed 1,000,000,000
334 /// in order to represent the [leap second](#leap-second-handling).
336 /// Panics on invalid hour, minute, second and/or nanosecond.
341 /// use chrono::{NaiveTime, Timelike};
343 /// let t = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
344 /// assert_eq!(t.hour(), 23);
345 /// assert_eq!(t.minute(), 56);
346 /// assert_eq!(t.second(), 4);
347 /// assert_eq!(t.nanosecond(), 12_345_678);
350 pub fn from_hms_nano(hour
: u32, min
: u32, sec
: u32, nano
: u32) -> NaiveTime
{
351 NaiveTime
::from_hms_nano_opt(hour
, min
, sec
, nano
).expect("invalid time")
354 /// Makes a new `NaiveTime` from hour, minute, second and nanosecond.
356 /// The nanosecond part can exceed 1,000,000,000
357 /// in order to represent the [leap second](#leap-second-handling).
359 /// Returns `None` on invalid hour, minute, second and/or nanosecond.
364 /// use chrono::NaiveTime;
366 /// let from_hmsn_opt = NaiveTime::from_hms_nano_opt;
368 /// assert!(from_hmsn_opt(0, 0, 0, 0).is_some());
369 /// assert!(from_hmsn_opt(23, 59, 59, 999_999_999).is_some());
370 /// assert!(from_hmsn_opt(23, 59, 59, 1_999_999_999).is_some()); // a leap second after 23:59:59
371 /// assert!(from_hmsn_opt(24, 0, 0, 0).is_none());
372 /// assert!(from_hmsn_opt(23, 60, 0, 0).is_none());
373 /// assert!(from_hmsn_opt(23, 59, 60, 0).is_none());
374 /// assert!(from_hmsn_opt(23, 59, 59, 2_000_000_000).is_none());
377 pub fn from_hms_nano_opt(hour
: u32, min
: u32, sec
: u32, nano
: u32) -> Option
<NaiveTime
> {
378 if hour
>= 24 || min
>= 60 || sec
>= 60 || nano
>= 2_000_000_000 { return None; }
379 let secs
= hour
* 3600 + min
* 60 + sec
;
380 Some(NaiveTime { secs: secs, frac: nano }
)
383 /// Makes a new `NaiveTime` from the number of seconds since midnight and nanosecond.
385 /// The nanosecond part can exceed 1,000,000,000
386 /// in order to represent the [leap second](#leap-second-handling).
388 /// Panics on invalid number of seconds and/or nanosecond.
393 /// use chrono::{NaiveTime, Timelike};
395 /// let t = NaiveTime::from_num_seconds_from_midnight(86164, 12_345_678);
396 /// assert_eq!(t.hour(), 23);
397 /// assert_eq!(t.minute(), 56);
398 /// assert_eq!(t.second(), 4);
399 /// assert_eq!(t.nanosecond(), 12_345_678);
402 pub fn from_num_seconds_from_midnight(secs
: u32, nano
: u32) -> NaiveTime
{
403 NaiveTime
::from_num_seconds_from_midnight_opt(secs
, nano
).expect("invalid time")
406 /// Makes a new `NaiveTime` from the number of seconds since midnight and nanosecond.
408 /// The nanosecond part can exceed 1,000,000,000
409 /// in order to represent the [leap second](#leap-second-handling).
411 /// Returns `None` on invalid number of seconds and/or nanosecond.
416 /// use chrono::NaiveTime;
418 /// let from_nsecs_opt = NaiveTime::from_num_seconds_from_midnight_opt;
420 /// assert!(from_nsecs_opt(0, 0).is_some());
421 /// assert!(from_nsecs_opt(86399, 999_999_999).is_some());
422 /// assert!(from_nsecs_opt(86399, 1_999_999_999).is_some()); // a leap second after 23:59:59
423 /// assert!(from_nsecs_opt(86_400, 0).is_none());
424 /// assert!(from_nsecs_opt(86399, 2_000_000_000).is_none());
427 pub fn from_num_seconds_from_midnight_opt(secs
: u32, nano
: u32) -> Option
<NaiveTime
> {
428 if secs
>= 86_400 || nano
>= 2_000_000_000 { return None; }
429 Some(NaiveTime { secs: secs, frac: nano }
)
432 /// Parses a string with the specified format string and returns a new `NaiveTime`.
433 /// See the [`format::strftime` module](../format/strftime/index.html)
434 /// on the supported escape sequences.
439 /// use chrono::NaiveTime;
441 /// let parse_from_str = NaiveTime::parse_from_str;
443 /// assert_eq!(parse_from_str("23:56:04", "%H:%M:%S"),
444 /// Ok(NaiveTime::from_hms(23, 56, 4)));
445 /// assert_eq!(parse_from_str("pm012345.6789", "%p%I%M%S%.f"),
446 /// Ok(NaiveTime::from_hms_micro(13, 23, 45, 678_900)));
449 /// Date and offset is ignored for the purpose of parsing.
452 /// # use chrono::NaiveTime;
453 /// # let parse_from_str = NaiveTime::parse_from_str;
454 /// assert_eq!(parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
455 /// Ok(NaiveTime::from_hms(12, 34, 56)));
458 /// [Leap seconds](#leap-second-handling) are correctly handled by
459 /// treating any time of the form `hh:mm:60` as a leap second.
460 /// (This equally applies to the formatting, so the round trip is possible.)
463 /// # use chrono::NaiveTime;
464 /// # let parse_from_str = NaiveTime::parse_from_str;
465 /// assert_eq!(parse_from_str("08:59:60.123", "%H:%M:%S%.f"),
466 /// Ok(NaiveTime::from_hms_milli(8, 59, 59, 1_123)));
469 /// Missing seconds are assumed to be zero,
470 /// but out-of-bound times or insufficient fields are errors otherwise.
473 /// # use chrono::NaiveTime;
474 /// # let parse_from_str = NaiveTime::parse_from_str;
475 /// assert_eq!(parse_from_str("7:15", "%H:%M"),
476 /// Ok(NaiveTime::from_hms(7, 15, 0)));
478 /// assert!(parse_from_str("04m33s", "%Mm%Ss").is_err());
479 /// assert!(parse_from_str("12", "%H").is_err());
480 /// assert!(parse_from_str("17:60", "%H:%M").is_err());
481 /// assert!(parse_from_str("24:00:00", "%H:%M:%S").is_err());
484 /// All parsed fields should be consistent to each other, otherwise it's an error.
485 /// Here `%H` is for 24-hour clocks, unlike `%I`,
486 /// and thus can be independently determined without AM/PM.
489 /// # use chrono::NaiveTime;
490 /// # let parse_from_str = NaiveTime::parse_from_str;
491 /// assert!(parse_from_str("13:07 AM", "%H:%M %p").is_err());
493 pub fn parse_from_str(s
: &str, fmt
: &str) -> ParseResult
<NaiveTime
> {
494 let mut parsed
= Parsed
::new();
495 try
!(parse(&mut parsed
, s
, StrftimeItems
::new(fmt
)));
496 parsed
.to_naive_time()
499 /// Adds given `Duration` to the current time,
500 /// and also returns the number of *seconds*
501 /// in the integral number of days ignored from the addition.
502 /// (We cannot return `Duration` because it is subject to overflow or underflow.)
507 /// # extern crate chrono; extern crate time; fn main() {
508 /// use chrono::NaiveTime;
509 /// use time::Duration;
511 /// let from_hms = NaiveTime::from_hms;
513 /// assert_eq!(from_hms(3, 4, 5).overflowing_add_signed(Duration::hours(11)),
514 /// (from_hms(14, 4, 5), 0));
515 /// assert_eq!(from_hms(3, 4, 5).overflowing_add_signed(Duration::hours(23)),
516 /// (from_hms(2, 4, 5), 86_400));
517 /// assert_eq!(from_hms(3, 4, 5).overflowing_add_signed(Duration::hours(-7)),
518 /// (from_hms(20, 4, 5), -86_400));
521 #[cfg_attr(feature = "cargo-clippy", allow(cyclomatic_complexity))]
522 pub fn overflowing_add_signed(&self, mut rhs
: OldDuration
) -> (NaiveTime
, i64) {
523 let mut secs
= self.secs
;
524 let mut frac
= self.frac
;
526 // check if `self` is a leap second and adding `rhs` would escape that leap second.
527 // if it's the case, update `self` and `rhs` to involve no leap second;
528 // otherwise the addition immediately finishes.
529 if frac
>= 1_000_000_000 {
530 let rfrac
= 2_000_000_000 - frac
;
531 if rhs
>= OldDuration
::nanoseconds(i64::from(rfrac
)) {
532 rhs
= rhs
- OldDuration
::nanoseconds(i64::from(rfrac
));
535 } else if rhs
< OldDuration
::nanoseconds(-i64::from(frac
)) {
536 rhs
= rhs
+ OldDuration
::nanoseconds(i64::from(frac
));
539 frac
= (i64::from(frac
) + rhs
.num_nanoseconds().unwrap()) as u32;
540 debug_assert
!(frac
< 2_000_000_000);
541 return (NaiveTime { secs: secs, frac: frac }
, 0);
544 debug_assert
!(secs
<= 86_400);
545 debug_assert
!(frac
< 1_000_000_000);
547 let rhssecs
= rhs
.num_seconds();
548 let rhsfrac
= (rhs
- OldDuration
::seconds(rhssecs
)).num_nanoseconds().unwrap();
549 debug_assert_eq
!(OldDuration
::seconds(rhssecs
) + OldDuration
::nanoseconds(rhsfrac
), rhs
);
550 let rhssecsinday
= rhssecs
% 86_400;
551 let mut morerhssecs
= rhssecs
- rhssecsinday
;
552 let rhssecs
= rhssecsinday
as i32;
553 let rhsfrac
= rhsfrac
as i32;
554 debug_assert
!(-86_400 < rhssecs
&& rhssecs
< 86_400);
555 debug_assert_eq
!(morerhssecs
% 86_400, 0);
556 debug_assert
!(-1_000_000_000 < rhsfrac
&& rhsfrac
< 1_000_000_000);
558 let mut secs
= secs
as i32 + rhssecs
;
559 let mut frac
= frac
as i32 + rhsfrac
;
560 debug_assert
!(-86_400 < secs
&& secs
< 2 * 86_400);
561 debug_assert
!(-1_000_000_000 < frac
&& frac
< 2_000_000_000);
564 frac
+= 1_000_000_000;
566 } else if frac
>= 1_000_000_000 {
567 frac
-= 1_000_000_000;
570 debug_assert
!(-86_400 <= secs
&& secs
< 2 * 86_400);
571 debug_assert
!(0 <= frac
&& frac
< 1_000_000_000);
575 morerhssecs
-= 86_400;
576 } else if secs
>= 86_400 {
578 morerhssecs
+= 86_400;
580 debug_assert
!(0 <= secs
&& secs
< 86_400);
582 (NaiveTime { secs: secs as u32, frac: frac as u32 }
, morerhssecs
)
585 /// Subtracts given `Duration` from the current time,
586 /// and also returns the number of *seconds*
587 /// in the integral number of days ignored from the subtraction.
588 /// (We cannot return `Duration` because it is subject to overflow or underflow.)
593 /// # extern crate chrono; extern crate time; fn main() {
594 /// use chrono::NaiveTime;
595 /// use time::Duration;
597 /// let from_hms = NaiveTime::from_hms;
599 /// assert_eq!(from_hms(3, 4, 5).overflowing_sub_signed(Duration::hours(2)),
600 /// (from_hms(1, 4, 5), 0));
601 /// assert_eq!(from_hms(3, 4, 5).overflowing_sub_signed(Duration::hours(17)),
602 /// (from_hms(10, 4, 5), 86_400));
603 /// assert_eq!(from_hms(3, 4, 5).overflowing_sub_signed(Duration::hours(-22)),
604 /// (from_hms(1, 4, 5), -86_400));
608 pub fn overflowing_sub_signed(&self, rhs
: OldDuration
) -> (NaiveTime
, i64) {
609 let (time
, rhs
) = self.overflowing_add_signed(-rhs
);
610 (time
, -rhs
) // safe to negate, rhs is within +/- (2^63 / 1000)
613 /// Subtracts another `NaiveTime` from the current time.
614 /// Returns a `Duration` within +/- 1 day.
615 /// This does not overflow or underflow at all.
617 /// As a part of Chrono's [leap second handling](#leap-second-handling),
618 /// the subtraction assumes that **there is no leap second ever**,
619 /// except when any of the `NaiveTime`s themselves represents a leap second
620 /// in which case the assumption becomes that
621 /// **there are exactly one (or two) leap second(s) ever**.
626 /// # extern crate chrono; extern crate time; fn main() {
627 /// use chrono::NaiveTime;
628 /// use time::Duration;
630 /// let from_hmsm = NaiveTime::from_hms_milli;
631 /// let since = NaiveTime::signed_duration_since;
633 /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 7, 900)),
634 /// Duration::zero());
635 /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 7, 875)),
636 /// Duration::milliseconds(25));
637 /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 6, 925)),
638 /// Duration::milliseconds(975));
639 /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 0, 900)),
640 /// Duration::seconds(7));
641 /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 0, 7, 900)),
642 /// Duration::seconds(5 * 60));
643 /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(0, 5, 7, 900)),
644 /// Duration::seconds(3 * 3600));
645 /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(4, 5, 7, 900)),
646 /// Duration::seconds(-3600));
647 /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(2, 4, 6, 800)),
648 /// Duration::seconds(3600 + 60 + 1) + Duration::milliseconds(100));
652 /// Leap seconds are handled, but the subtraction assumes that
653 /// there were no other leap seconds happened.
656 /// # extern crate chrono; extern crate time; fn main() {
657 /// # use chrono::NaiveTime;
658 /// # use time::Duration;
659 /// # let from_hmsm = NaiveTime::from_hms_milli;
660 /// # let since = NaiveTime::signed_duration_since;
661 /// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(3, 0, 59, 0)),
662 /// Duration::seconds(1));
663 /// assert_eq!(since(from_hmsm(3, 0, 59, 1_500), from_hmsm(3, 0, 59, 0)),
664 /// Duration::milliseconds(1500));
665 /// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(3, 0, 0, 0)),
666 /// Duration::seconds(60));
667 /// assert_eq!(since(from_hmsm(3, 0, 0, 0), from_hmsm(2, 59, 59, 1_000)),
668 /// Duration::seconds(1));
669 /// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(2, 59, 59, 1_000)),
670 /// Duration::seconds(61));
673 pub fn signed_duration_since(self, rhs
: NaiveTime
) -> OldDuration
{
674 // | | :leap| | | | | | | :leap| |
675 // | | : | | | | | | | : | |
676 // ----+----+-----*---+----+----+----+----+----+----+-------*-+----+----
677 // | `rhs` | | `self`
678 // |======================================>| |
679 // | | `self.secs - rhs.secs` |`self.frac`
680 // |====>| | |======>|
681 // `rhs.frac`|========================================>|
682 // | | | `self - rhs` | |
684 use std
::cmp
::Ordering
;
686 let secs
= i64::from(self.secs
) - i64::from(rhs
.secs
);
687 let frac
= i64::from(self.frac
) - i64::from(rhs
.frac
);
689 // `secs` may contain a leap second yet to be counted
690 let adjust
= match self.secs
.cmp(&rhs
.secs
) {
691 Ordering
::Greater
=> if rhs
.frac
>= 1_000_000_000 { 1 }
else { 0 }
,
692 Ordering
::Equal
=> 0,
693 Ordering
::Less
=> if self.frac
>= 1_000_000_000 { -1 }
else { 0 }
,
696 OldDuration
::seconds(secs
+ adjust
) + OldDuration
::nanoseconds(frac
)
699 /// Formats the time with the specified formatting items.
700 /// Otherwise it is same to the ordinary [`format`](#method.format) method.
702 /// The `Iterator` of items should be `Clone`able,
703 /// since the resulting `DelayedFormat` value may be formatted multiple times.
708 /// use chrono::NaiveTime;
709 /// use chrono::format::strftime::StrftimeItems;
711 /// let fmt = StrftimeItems::new("%H:%M:%S");
712 /// let t = NaiveTime::from_hms(23, 56, 4);
713 /// assert_eq!(t.format_with_items(fmt.clone()).to_string(), "23:56:04");
714 /// assert_eq!(t.format("%H:%M:%S").to_string(), "23:56:04");
717 /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
720 /// # use chrono::NaiveTime;
721 /// # use chrono::format::strftime::StrftimeItems;
722 /// # let fmt = StrftimeItems::new("%H:%M:%S").clone();
723 /// # let t = NaiveTime::from_hms(23, 56, 4);
724 /// assert_eq!(format!("{}", t.format_with_items(fmt)), "23:56:04");
727 pub fn format_with_items
<'a
, I
>(&self, items
: I
) -> DelayedFormat
<I
>
728 where I
: Iterator
<Item
=Item
<'a
>> + Clone
{
729 DelayedFormat
::new(None
, Some(*self), items
)
732 /// Formats the time with the specified format string.
733 /// See the [`format::strftime` module](../format/strftime/index.html)
734 /// on the supported escape sequences.
736 /// This returns a `DelayedFormat`,
737 /// which gets converted to a string only when actual formatting happens.
738 /// You may use the `to_string` method to get a `String`,
739 /// or just feed it into `print!` and other formatting macros.
740 /// (In this way it avoids the redundant memory allocation.)
742 /// A wrong format string does *not* issue an error immediately.
743 /// Rather, converting or formatting the `DelayedFormat` fails.
744 /// You are recommended to immediately use `DelayedFormat` for this reason.
749 /// use chrono::NaiveTime;
751 /// let t = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
752 /// assert_eq!(t.format("%H:%M:%S").to_string(), "23:56:04");
753 /// assert_eq!(t.format("%H:%M:%S%.6f").to_string(), "23:56:04.012345");
754 /// assert_eq!(t.format("%-I:%M %p").to_string(), "11:56 PM");
757 /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
760 /// # use chrono::NaiveTime;
761 /// # let t = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
762 /// assert_eq!(format!("{}", t.format("%H:%M:%S")), "23:56:04");
763 /// assert_eq!(format!("{}", t.format("%H:%M:%S%.6f")), "23:56:04.012345");
764 /// assert_eq!(format!("{}", t.format("%-I:%M %p")), "11:56 PM");
767 pub fn format
<'a
>(&self, fmt
: &'a
str) -> DelayedFormat
<StrftimeItems
<'a
>> {
768 self.format_with_items(StrftimeItems
::new(fmt
))
771 /// Returns a triple of the hour, minute and second numbers.
772 fn hms(&self) -> (u32, u32, u32) {
773 let (mins
, sec
) = div_mod_floor(self.secs
, 60);
774 let (hour
, min
) = div_mod_floor(mins
, 60);
779 impl Timelike
for NaiveTime
{
780 /// Returns the hour number from 0 to 23.
785 /// use chrono::{NaiveTime, Timelike};
787 /// assert_eq!(NaiveTime::from_hms(0, 0, 0).hour(), 0);
788 /// assert_eq!(NaiveTime::from_hms_nano(23, 56, 4, 12_345_678).hour(), 23);
791 fn hour(&self) -> u32 {
795 /// Returns the minute number from 0 to 59.
800 /// use chrono::{NaiveTime, Timelike};
802 /// assert_eq!(NaiveTime::from_hms(0, 0, 0).minute(), 0);
803 /// assert_eq!(NaiveTime::from_hms_nano(23, 56, 4, 12_345_678).minute(), 56);
806 fn minute(&self) -> u32 {
810 /// Returns the second number from 0 to 59.
815 /// use chrono::{NaiveTime, Timelike};
817 /// assert_eq!(NaiveTime::from_hms(0, 0, 0).second(), 0);
818 /// assert_eq!(NaiveTime::from_hms_nano(23, 56, 4, 12_345_678).second(), 4);
821 /// This method never returns 60 even when it is a leap second.
822 /// ([Why?](#leap-second-handling))
823 /// Use the proper [formatting method](#method.format) to get a human-readable representation.
826 /// # use chrono::{NaiveTime, Timelike};
827 /// let leap = NaiveTime::from_hms_milli(23, 59, 59, 1_000);
828 /// assert_eq!(leap.second(), 59);
829 /// assert_eq!(leap.format("%H:%M:%S").to_string(), "23:59:60");
832 fn second(&self) -> u32 {
836 /// Returns the number of nanoseconds since the whole non-leap second.
837 /// The range from 1,000,000,000 to 1,999,999,999 represents
838 /// the [leap second](#leap-second-handling).
843 /// use chrono::{NaiveTime, Timelike};
845 /// assert_eq!(NaiveTime::from_hms(0, 0, 0).nanosecond(), 0);
846 /// assert_eq!(NaiveTime::from_hms_nano(23, 56, 4, 12_345_678).nanosecond(), 12_345_678);
849 /// Leap seconds may have seemingly out-of-range return values.
850 /// You can reduce the range with `time.nanosecond() % 1_000_000_000`, or
851 /// use the proper [formatting method](#method.format) to get a human-readable representation.
854 /// # use chrono::{NaiveTime, Timelike};
855 /// let leap = NaiveTime::from_hms_milli(23, 59, 59, 1_000);
856 /// assert_eq!(leap.nanosecond(), 1_000_000_000);
857 /// assert_eq!(leap.format("%H:%M:%S%.9f").to_string(), "23:59:60.000000000");
860 fn nanosecond(&self) -> u32 {
864 /// Makes a new `NaiveTime` with the hour number changed.
866 /// Returns `None` when the resulting `NaiveTime` would be invalid.
871 /// use chrono::{NaiveTime, Timelike};
873 /// let dt = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
874 /// assert_eq!(dt.with_hour(7), Some(NaiveTime::from_hms_nano(7, 56, 4, 12_345_678)));
875 /// assert_eq!(dt.with_hour(24), None);
878 fn with_hour(&self, hour
: u32) -> Option
<NaiveTime
> {
879 if hour
>= 24 { return None; }
880 let secs
= hour
* 3600 + self.secs
% 3600;
881 Some(NaiveTime { secs: secs, ..*self }
)
884 /// Makes a new `NaiveTime` with the minute number changed.
886 /// Returns `None` when the resulting `NaiveTime` would be invalid.
891 /// use chrono::{NaiveTime, Timelike};
893 /// let dt = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
894 /// assert_eq!(dt.with_minute(45), Some(NaiveTime::from_hms_nano(23, 45, 4, 12_345_678)));
895 /// assert_eq!(dt.with_minute(60), None);
898 fn with_minute(&self, min
: u32) -> Option
<NaiveTime
> {
899 if min
>= 60 { return None; }
900 let secs
= self.secs
/ 3600 * 3600 + min
* 60 + self.secs
% 60;
901 Some(NaiveTime { secs: secs, ..*self }
)
904 /// Makes a new `NaiveTime` with the second number changed.
906 /// Returns `None` when the resulting `NaiveTime` would be invalid.
907 /// As with the [`second`](#method.second) method,
908 /// the input range is restricted to 0 through 59.
913 /// use chrono::{NaiveTime, Timelike};
915 /// let dt = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
916 /// assert_eq!(dt.with_second(17), Some(NaiveTime::from_hms_nano(23, 56, 17, 12_345_678)));
917 /// assert_eq!(dt.with_second(60), None);
920 fn with_second(&self, sec
: u32) -> Option
<NaiveTime
> {
921 if sec
>= 60 { return None; }
922 let secs
= self.secs
/ 60 * 60 + sec
;
923 Some(NaiveTime { secs: secs, ..*self }
)
926 /// Makes a new `NaiveTime` with nanoseconds since the whole non-leap second changed.
928 /// Returns `None` when the resulting `NaiveTime` would be invalid.
929 /// As with the [`nanosecond`](#method.nanosecond) method,
930 /// the input range can exceed 1,000,000,000 for leap seconds.
935 /// use chrono::{NaiveTime, Timelike};
937 /// let dt = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
938 /// assert_eq!(dt.with_nanosecond(333_333_333),
939 /// Some(NaiveTime::from_hms_nano(23, 56, 4, 333_333_333)));
940 /// assert_eq!(dt.with_nanosecond(2_000_000_000), None);
943 /// Leap seconds can theoretically follow *any* whole second.
944 /// The following would be a proper leap second at the time zone offset of UTC-00:03:57
945 /// (there are several historical examples comparable to this "non-sense" offset),
946 /// and therefore is allowed.
949 /// # use chrono::{NaiveTime, Timelike};
950 /// # let dt = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
951 /// assert_eq!(dt.with_nanosecond(1_333_333_333),
952 /// Some(NaiveTime::from_hms_nano(23, 56, 4, 1_333_333_333)));
955 fn with_nanosecond(&self, nano
: u32) -> Option
<NaiveTime
> {
956 if nano
>= 2_000_000_000 { return None; }
957 Some(NaiveTime { frac: nano, ..*self }
)
960 /// Returns the number of non-leap seconds past the last midnight.
965 /// use chrono::{NaiveTime, Timelike};
967 /// assert_eq!(NaiveTime::from_hms(1, 2, 3).num_seconds_from_midnight(),
969 /// assert_eq!(NaiveTime::from_hms_nano(23, 56, 4, 12_345_678).num_seconds_from_midnight(),
971 /// assert_eq!(NaiveTime::from_hms_milli(23, 59, 59, 1_000).num_seconds_from_midnight(),
975 fn num_seconds_from_midnight(&self) -> u32 {
976 self.secs
// do not repeat the calculation!
980 /// `NaiveTime` can be used as a key to the hash maps (in principle).
982 /// Practically this also takes account of fractional seconds, so it is not recommended.
983 /// (For the obvious reason this also distinguishes leap seconds from non-leap seconds.)
984 #[cfg_attr(feature = "cargo-clippy", allow(derive_hash_xor_eq))]
985 impl hash
::Hash
for NaiveTime
{
986 fn hash
<H
: hash
::Hasher
>(&self, state
: &mut H
) {
987 self.secs
.hash(state
);
988 self.frac
.hash(state
);
992 /// An addition of `Duration` to `NaiveTime` wraps around and never overflows or underflows.
993 /// In particular the addition ignores integral number of days.
995 /// As a part of Chrono's [leap second handling](#leap-second-handling),
996 /// the addition assumes that **there is no leap second ever**,
997 /// except when the `NaiveTime` itself represents a leap second
998 /// in which case the assumption becomes that **there is exactly a single leap second ever**.
1003 /// # extern crate chrono; extern crate time; fn main() {
1004 /// use chrono::NaiveTime;
1005 /// use time::Duration;
1007 /// let from_hmsm = NaiveTime::from_hms_milli;
1009 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::zero(), from_hmsm(3, 5, 7, 0));
1010 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(1), from_hmsm(3, 5, 8, 0));
1011 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(-1), from_hmsm(3, 5, 6, 0));
1012 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(60 + 4), from_hmsm(3, 6, 11, 0));
1013 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(7*60*60 - 6*60), from_hmsm(9, 59, 7, 0));
1014 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::milliseconds(80), from_hmsm(3, 5, 7, 80));
1015 /// assert_eq!(from_hmsm(3, 5, 7, 950) + Duration::milliseconds(280), from_hmsm(3, 5, 8, 230));
1016 /// assert_eq!(from_hmsm(3, 5, 7, 950) + Duration::milliseconds(-980), from_hmsm(3, 5, 6, 970));
1020 /// The addition wraps around.
1023 /// # extern crate chrono; extern crate time; fn main() {
1024 /// # use chrono::NaiveTime;
1025 /// # use time::Duration;
1026 /// # let from_hmsm = NaiveTime::from_hms_milli;
1027 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(22*60*60), from_hmsm(1, 5, 7, 0));
1028 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(-8*60*60), from_hmsm(19, 5, 7, 0));
1029 /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::days(800), from_hmsm(3, 5, 7, 0));
1033 /// Leap seconds are handled, but the addition assumes that it is the only leap second happened.
1036 /// # extern crate chrono; extern crate time; fn main() {
1037 /// # use chrono::NaiveTime;
1038 /// # use time::Duration;
1039 /// # let from_hmsm = NaiveTime::from_hms_milli;
1040 /// let leap = from_hmsm(3, 5, 59, 1_300);
1041 /// assert_eq!(leap + Duration::zero(), from_hmsm(3, 5, 59, 1_300));
1042 /// assert_eq!(leap + Duration::milliseconds(-500), from_hmsm(3, 5, 59, 800));
1043 /// assert_eq!(leap + Duration::milliseconds(500), from_hmsm(3, 5, 59, 1_800));
1044 /// assert_eq!(leap + Duration::milliseconds(800), from_hmsm(3, 6, 0, 100));
1045 /// assert_eq!(leap + Duration::seconds(10), from_hmsm(3, 6, 9, 300));
1046 /// assert_eq!(leap + Duration::seconds(-10), from_hmsm(3, 5, 50, 300));
1047 /// assert_eq!(leap + Duration::days(1), from_hmsm(3, 5, 59, 300));
1050 impl Add
<OldDuration
> for NaiveTime
{
1051 type Output
= NaiveTime
;
1054 fn add(self, rhs
: OldDuration
) -> NaiveTime
{
1055 self.overflowing_add_signed(rhs
).0
1059 impl AddAssign
<OldDuration
> for NaiveTime
{
1061 fn add_assign(&mut self, rhs
: OldDuration
) {
1062 *self = self.add(rhs
);
1066 /// A subtraction of `Duration` from `NaiveTime` wraps around and never overflows or underflows.
1067 /// In particular the addition ignores integral number of days.
1068 /// It is same to the addition with a negated `Duration`.
1070 /// As a part of Chrono's [leap second handling](#leap-second-handling),
1071 /// the addition assumes that **there is no leap second ever**,
1072 /// except when the `NaiveTime` itself represents a leap second
1073 /// in which case the assumption becomes that **there is exactly a single leap second ever**.
1078 /// # extern crate chrono; extern crate time; fn main() {
1079 /// use chrono::NaiveTime;
1080 /// use time::Duration;
1082 /// let from_hmsm = NaiveTime::from_hms_milli;
1084 /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::zero(), from_hmsm(3, 5, 7, 0));
1085 /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::seconds(1), from_hmsm(3, 5, 6, 0));
1086 /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::seconds(60 + 5), from_hmsm(3, 4, 2, 0));
1087 /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::seconds(2*60*60 + 6*60), from_hmsm(0, 59, 7, 0));
1088 /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::milliseconds(80), from_hmsm(3, 5, 6, 920));
1089 /// assert_eq!(from_hmsm(3, 5, 7, 950) - Duration::milliseconds(280), from_hmsm(3, 5, 7, 670));
1093 /// The subtraction wraps around.
1096 /// # extern crate chrono; extern crate time; fn main() {
1097 /// # use chrono::NaiveTime;
1098 /// # use time::Duration;
1099 /// # let from_hmsm = NaiveTime::from_hms_milli;
1100 /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::seconds(8*60*60), from_hmsm(19, 5, 7, 0));
1101 /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::days(800), from_hmsm(3, 5, 7, 0));
1105 /// Leap seconds are handled, but the subtraction assumes that it is the only leap second happened.
1108 /// # extern crate chrono; extern crate time; fn main() {
1109 /// # use chrono::NaiveTime;
1110 /// # use time::Duration;
1111 /// # let from_hmsm = NaiveTime::from_hms_milli;
1112 /// let leap = from_hmsm(3, 5, 59, 1_300);
1113 /// assert_eq!(leap - Duration::zero(), from_hmsm(3, 5, 59, 1_300));
1114 /// assert_eq!(leap - Duration::milliseconds(200), from_hmsm(3, 5, 59, 1_100));
1115 /// assert_eq!(leap - Duration::milliseconds(500), from_hmsm(3, 5, 59, 800));
1116 /// assert_eq!(leap - Duration::seconds(60), from_hmsm(3, 5, 0, 300));
1117 /// assert_eq!(leap - Duration::days(1), from_hmsm(3, 6, 0, 300));
1120 impl Sub
<OldDuration
> for NaiveTime
{
1121 type Output
= NaiveTime
;
1124 fn sub(self, rhs
: OldDuration
) -> NaiveTime
{
1125 self.overflowing_sub_signed(rhs
).0
1129 impl SubAssign
<OldDuration
> for NaiveTime
{
1131 fn sub_assign(&mut self, rhs
: OldDuration
) {
1132 *self = self.sub(rhs
);
1136 /// The `Debug` output of the naive time `t` is same to
1137 /// [`t.format("%H:%M:%S%.f")`](../format/strftime/index.html).
1139 /// The string printed can be readily parsed via the `parse` method on `str`.
1141 /// It should be noted that, for leap seconds not on the minute boundary,
1142 /// it may print a representation not distinguishable from non-leap seconds.
1143 /// This doesn't matter in practice, since such leap seconds never happened.
1144 /// (By the time of the first leap second on 1972-06-30,
1145 /// every time zone offset around the world has standardized to the 5-minute alignment.)
1150 /// use chrono::NaiveTime;
1152 /// assert_eq!(format!("{:?}", NaiveTime::from_hms(23, 56, 4)), "23:56:04");
1153 /// assert_eq!(format!("{:?}", NaiveTime::from_hms_milli(23, 56, 4, 12)), "23:56:04.012");
1154 /// assert_eq!(format!("{:?}", NaiveTime::from_hms_micro(23, 56, 4, 1234)), "23:56:04.001234");
1155 /// assert_eq!(format!("{:?}", NaiveTime::from_hms_nano(23, 56, 4, 123456)), "23:56:04.000123456");
1158 /// Leap seconds may also be used.
1161 /// # use chrono::NaiveTime;
1162 /// assert_eq!(format!("{:?}", NaiveTime::from_hms_milli(6, 59, 59, 1_500)), "06:59:60.500");
1164 impl fmt
::Debug
for NaiveTime
{
1165 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
1166 let (hour
, min
, sec
) = self.hms();
1167 let (sec
, nano
) = if self.frac
>= 1_000_000_000 {
1168 (sec
+ 1, self.frac
- 1_000_000_000)
1173 try
!(write
!(f
, "{:02}:{:02}:{:02}", hour
, min
, sec
));
1176 } else if nano
% 1_000_000 == 0 {
1177 write
!(f
, ".{:03}", nano
/ 1_000_000)
1178 } else if nano
% 1_000 == 0 {
1179 write
!(f
, ".{:06}", nano
/ 1_000)
1181 write
!(f
, ".{:09}", nano
)
1186 /// The `Display` output of the naive time `t` is same to
1187 /// [`t.format("%H:%M:%S%.f")`](../format/strftime/index.html).
1189 /// The string printed can be readily parsed via the `parse` method on `str`.
1191 /// It should be noted that, for leap seconds not on the minute boundary,
1192 /// it may print a representation not distinguishable from non-leap seconds.
1193 /// This doesn't matter in practice, since such leap seconds never happened.
1194 /// (By the time of the first leap second on 1972-06-30,
1195 /// every time zone offset around the world has standardized to the 5-minute alignment.)
1200 /// use chrono::NaiveTime;
1202 /// assert_eq!(format!("{}", NaiveTime::from_hms(23, 56, 4)), "23:56:04");
1203 /// assert_eq!(format!("{}", NaiveTime::from_hms_milli(23, 56, 4, 12)), "23:56:04.012");
1204 /// assert_eq!(format!("{}", NaiveTime::from_hms_micro(23, 56, 4, 1234)), "23:56:04.001234");
1205 /// assert_eq!(format!("{}", NaiveTime::from_hms_nano(23, 56, 4, 123456)), "23:56:04.000123456");
1208 /// Leap seconds may also be used.
1211 /// # use chrono::NaiveTime;
1212 /// assert_eq!(format!("{}", NaiveTime::from_hms_milli(6, 59, 59, 1_500)), "06:59:60.500");
1214 impl fmt
::Display
for NaiveTime
{
1215 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result { fmt::Debug::fmt(self, f) }
1218 /// Parsing a `str` into a `NaiveTime` uses the same format,
1219 /// [`%H:%M:%S%.f`](../format/strftime/index.html), as in `Debug` and `Display`.
1224 /// use chrono::NaiveTime;
1226 /// let t = NaiveTime::from_hms(23, 56, 4);
1227 /// assert_eq!("23:56:04".parse::<NaiveTime>(), Ok(t));
1229 /// let t = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
1230 /// assert_eq!("23:56:4.012345678".parse::<NaiveTime>(), Ok(t));
1232 /// let t = NaiveTime::from_hms_nano(23, 59, 59, 1_234_567_890); // leap second
1233 /// assert_eq!("23:59:60.23456789".parse::<NaiveTime>(), Ok(t));
1235 /// assert!("foo".parse::<NaiveTime>().is_err());
1237 impl str::FromStr
for NaiveTime
{
1238 type Err
= ParseError
;
1240 fn from_str(s
: &str) -> ParseResult
<NaiveTime
> {
1241 const ITEMS
: &'
static [Item
<'
static>] = &[
1242 Item
::Space(""), Item
::Numeric(Numeric
::Hour
, Pad
::Zero
),
1243 Item
::Space(""), Item
::Literal(":"),
1244 Item
::Space(""), Item
::Numeric(Numeric
::Minute
, Pad
::Zero
),
1245 Item
::Space(""), Item
::Literal(":"),
1246 Item
::Space(""), Item
::Numeric(Numeric
::Second
, Pad
::Zero
),
1247 Item
::Fixed(Fixed
::Nanosecond
), Item
::Space(""),
1250 let mut parsed
= Parsed
::new();
1251 try
!(parse(&mut parsed
, s
, ITEMS
.iter().cloned()));
1252 parsed
.to_naive_time()
1256 #[cfg(all(test, any(feature = "rustc-serialize", feature = "serde")))]
1257 fn test_encodable_json
<F
, E
>(to_string
: F
)
1258 where F
: Fn(&NaiveTime
) -> Result
<String
, E
>, E
: ::std
::fmt
::Debug
1260 assert_eq
!(to_string(&NaiveTime
::from_hms(0, 0, 0)).ok(),
1261 Some(r
#""00:00:00""#.into()));
1262 assert_eq
!(to_string(&NaiveTime
::from_hms_milli(0, 0, 0, 950)).ok(),
1263 Some(r
#""00:00:00.950""#.into()));
1264 assert_eq
!(to_string(&NaiveTime
::from_hms_milli(0, 0, 59, 1_000)).ok(),
1265 Some(r
#""00:00:60""#.into()));
1266 assert_eq
!(to_string(&NaiveTime
::from_hms(0, 1, 2)).ok(),
1267 Some(r
#""00:01:02""#.into()));
1268 assert_eq
!(to_string(&NaiveTime
::from_hms_nano(3, 5, 7, 98765432)).ok(),
1269 Some(r
#""03:05:07.098765432""#.into()));
1270 assert_eq
!(to_string(&NaiveTime
::from_hms(7, 8, 9)).ok(),
1271 Some(r
#""07:08:09""#.into()));
1272 assert_eq
!(to_string(&NaiveTime
::from_hms_micro(12, 34, 56, 789)).ok(),
1273 Some(r
#""12:34:56.000789""#.into()));
1274 assert_eq
!(to_string(&NaiveTime
::from_hms_nano(23, 59, 59, 1_999_999_999)).ok(),
1275 Some(r
#""23:59:60.999999999""#.into()));
1278 #[cfg(all(test, any(feature = "rustc-serialize", feature = "serde")))]
1279 fn test_decodable_json
<F
, E
>(from_str
: F
)
1280 where F
: Fn(&str) -> Result
<NaiveTime
, E
>, E
: ::std
::fmt
::Debug
1282 assert_eq
!(from_str(r
#""00:00:00""#).ok(),
1283 Some(NaiveTime
::from_hms(0, 0, 0)));
1284 assert_eq
!(from_str(r
#""0:0:0""#).ok(),
1285 Some(NaiveTime
::from_hms(0, 0, 0)));
1286 assert_eq
!(from_str(r
#""00:00:00.950""#).ok(),
1287 Some(NaiveTime
::from_hms_milli(0, 0, 0, 950)));
1288 assert_eq
!(from_str(r
#""0:0:0.95""#).ok(),
1289 Some(NaiveTime
::from_hms_milli(0, 0, 0, 950)));
1290 assert_eq
!(from_str(r
#""00:00:60""#).ok(),
1291 Some(NaiveTime
::from_hms_milli(0, 0, 59, 1_000)));
1292 assert_eq
!(from_str(r
#""00:01:02""#).ok(),
1293 Some(NaiveTime
::from_hms(0, 1, 2)));
1294 assert_eq
!(from_str(r
#""03:05:07.098765432""#).ok(),
1295 Some(NaiveTime
::from_hms_nano(3, 5, 7, 98765432)));
1296 assert_eq
!(from_str(r
#""07:08:09""#).ok(),
1297 Some(NaiveTime
::from_hms(7, 8, 9)));
1298 assert_eq
!(from_str(r
#""12:34:56.000789""#).ok(),
1299 Some(NaiveTime
::from_hms_micro(12, 34, 56, 789)));
1300 assert_eq
!(from_str(r
#""23:59:60.999999999""#).ok(),
1301 Some(NaiveTime
::from_hms_nano(23, 59, 59, 1_999_999_999)));
1302 assert_eq
!(from_str(r
#""23:59:60.9999999999997""#).ok(), // excess digits are ignored
1303 Some(NaiveTime
::from_hms_nano(23, 59, 59, 1_999_999_999)));
1306 assert
!(from_str(r
#""""#).is_err());
1307 assert
!(from_str(r
#""000000""#).is_err());
1308 assert
!(from_str(r
#""00:00:61""#).is_err());
1309 assert
!(from_str(r
#""00:60:00""#).is_err());
1310 assert
!(from_str(r
#""24:00:00""#).is_err());
1311 assert
!(from_str(r
#""23:59:59,1""#).is_err());
1312 assert
!(from_str(r
#""012:34:56""#).is_err());
1313 assert
!(from_str(r
#""hh:mm:ss""#).is_err());
1314 assert
!(from_str(r
#"0"#).is_err());
1315 assert
!(from_str(r
#"86399"#).is_err());
1316 assert
!(from_str(r
#"{}"#).is_err());
1317 // pre-0.3.0 rustc-serialize format is now invalid
1318 assert
!(from_str(r
#"{"secs":0,"frac":0}"#).is_err());
1319 assert
!(from_str(r
#"null"#).is_err());
1322 #[cfg(feature = "rustc-serialize")]
1323 mod rustc_serialize
{
1324 use super::NaiveTime
;
1325 use rustc_serialize
::{Encodable, Encoder, Decodable, Decoder}
;
1327 impl Encodable
for NaiveTime
{
1328 fn encode
<S
: Encoder
>(&self, s
: &mut S
) -> Result
<(), S
::Error
> {
1329 format
!("{:?}", self).encode(s
)
1333 impl Decodable
for NaiveTime
{
1334 fn decode
<D
: Decoder
>(d
: &mut D
) -> Result
<NaiveTime
, D
::Error
> {
1335 d
.read_str()?
.parse().map_err(|_
| d
.error("invalid time"))
1339 #[cfg(test)] use rustc_serialize::json;
1342 fn test_encodable() {
1343 super::test_encodable_json(json
::encode
);
1347 fn test_decodable() {
1348 super::test_decodable_json(json
::decode
);
1352 #[cfg(feature = "serde")]
1355 use super::NaiveTime
;
1356 use serdelib
::{ser, de}
;
1358 // TODO not very optimized for space (binary formats would want something better)
1359 // TODO round-trip for general leap seconds (not just those with second = 60)
1361 impl ser
::Serialize
for NaiveTime
{
1362 fn serialize
<S
>(&self, serializer
: S
) -> Result
<S
::Ok
, S
::Error
>
1363 where S
: ser
::Serializer
1365 serializer
.collect_str(&self)
1369 struct NaiveTimeVisitor
;
1371 impl<'de
> de
::Visitor
<'de
> for NaiveTimeVisitor
{
1372 type Value
= NaiveTime
;
1374 fn expecting(&self, formatter
: &mut fmt
::Formatter
) -> fmt
::Result
1376 write
!(formatter
, "a formatted time string")
1379 fn visit_str
<E
>(self, value
: &str) -> Result
<NaiveTime
, E
>
1382 value
.parse().map_err(|err
| E
::custom(format
!("{}", err
)))
1386 impl<'de
> de
::Deserialize
<'de
> for NaiveTime
{
1387 fn deserialize
<D
>(deserializer
: D
) -> Result
<Self, D
::Error
>
1388 where D
: de
::Deserializer
<'de
>
1390 deserializer
.deserialize_str(NaiveTimeVisitor
)
1394 #[cfg(test)] extern crate serde_json;
1395 #[cfg(test)] extern crate bincode;
1398 fn test_serde_serialize() {
1399 super::test_encodable_json(self::serde_json
::to_string
);
1403 fn test_serde_deserialize() {
1404 super::test_decodable_json(|input
| self::serde_json
::from_str(&input
));
1408 fn test_serde_bincode() {
1409 // Bincode is relevant to test separately from JSON because
1410 // it is not self-describing.
1411 use self::bincode
::{Infinite, serialize, deserialize}
;
1413 let t
= NaiveTime
::from_hms_nano(3, 5, 7, 98765432);
1414 let encoded
= serialize(&t
, Infinite
).unwrap();
1415 let decoded
: NaiveTime
= deserialize(&encoded
).unwrap();
1416 assert_eq
!(t
, decoded
);
1422 use super::NaiveTime
;
1425 use oldtime
::Duration
;
1428 fn test_time_from_hms_milli() {
1429 assert_eq
!(NaiveTime
::from_hms_milli_opt(3, 5, 7, 0),
1430 Some(NaiveTime
::from_hms_nano(3, 5, 7, 0)));
1431 assert_eq
!(NaiveTime
::from_hms_milli_opt(3, 5, 7, 777),
1432 Some(NaiveTime
::from_hms_nano(3, 5, 7, 777_000_000)));
1433 assert_eq
!(NaiveTime
::from_hms_milli_opt(3, 5, 7, 1_999),
1434 Some(NaiveTime
::from_hms_nano(3, 5, 7, 1_999_000_000)));
1435 assert_eq
!(NaiveTime
::from_hms_milli_opt(3, 5, 7, 2_000), None
);
1436 assert_eq
!(NaiveTime
::from_hms_milli_opt(3, 5, 7, 5_000), None
); // overflow check
1437 assert_eq
!(NaiveTime
::from_hms_milli_opt(3, 5, 7, u32::MAX
), None
);
1441 fn test_time_from_hms_micro() {
1442 assert_eq
!(NaiveTime
::from_hms_micro_opt(3, 5, 7, 0),
1443 Some(NaiveTime
::from_hms_nano(3, 5, 7, 0)));
1444 assert_eq
!(NaiveTime
::from_hms_micro_opt(3, 5, 7, 333),
1445 Some(NaiveTime
::from_hms_nano(3, 5, 7, 333_000)));
1446 assert_eq
!(NaiveTime
::from_hms_micro_opt(3, 5, 7, 777_777),
1447 Some(NaiveTime
::from_hms_nano(3, 5, 7, 777_777_000)));
1448 assert_eq
!(NaiveTime
::from_hms_micro_opt(3, 5, 7, 1_999_999),
1449 Some(NaiveTime
::from_hms_nano(3, 5, 7, 1_999_999_000)));
1450 assert_eq
!(NaiveTime
::from_hms_micro_opt(3, 5, 7, 2_000_000), None
);
1451 assert_eq
!(NaiveTime
::from_hms_micro_opt(3, 5, 7, 5_000_000), None
); // overflow check
1452 assert_eq
!(NaiveTime
::from_hms_micro_opt(3, 5, 7, u32::MAX
), None
);
1456 fn test_time_hms() {
1457 assert_eq
!(NaiveTime
::from_hms(3, 5, 7).hour(), 3);
1458 assert_eq
!(NaiveTime
::from_hms(3, 5, 7).with_hour(0),
1459 Some(NaiveTime
::from_hms(0, 5, 7)));
1460 assert_eq
!(NaiveTime
::from_hms(3, 5, 7).with_hour(23),
1461 Some(NaiveTime
::from_hms(23, 5, 7)));
1462 assert_eq
!(NaiveTime
::from_hms(3, 5, 7).with_hour(24), None
);
1463 assert_eq
!(NaiveTime
::from_hms(3, 5, 7).with_hour(u32::MAX
), None
);
1465 assert_eq
!(NaiveTime
::from_hms(3, 5, 7).minute(), 5);
1466 assert_eq
!(NaiveTime
::from_hms(3, 5, 7).with_minute(0),
1467 Some(NaiveTime
::from_hms(3, 0, 7)));
1468 assert_eq
!(NaiveTime
::from_hms(3, 5, 7).with_minute(59),
1469 Some(NaiveTime
::from_hms(3, 59, 7)));
1470 assert_eq
!(NaiveTime
::from_hms(3, 5, 7).with_minute(60), None
);
1471 assert_eq
!(NaiveTime
::from_hms(3, 5, 7).with_minute(u32::MAX
), None
);
1473 assert_eq
!(NaiveTime
::from_hms(3, 5, 7).second(), 7);
1474 assert_eq
!(NaiveTime
::from_hms(3, 5, 7).with_second(0),
1475 Some(NaiveTime
::from_hms(3, 5, 0)));
1476 assert_eq
!(NaiveTime
::from_hms(3, 5, 7).with_second(59),
1477 Some(NaiveTime
::from_hms(3, 5, 59)));
1478 assert_eq
!(NaiveTime
::from_hms(3, 5, 7).with_second(60), None
);
1479 assert_eq
!(NaiveTime
::from_hms(3, 5, 7).with_second(u32::MAX
), None
);
1483 fn test_time_add() {
1484 macro_rules
! check
{
1485 ($lhs
:expr
, $rhs
:expr
, $sum
:expr
) => ({
1486 assert_eq
!($lhs
+ $rhs
, $sum
);
1487 //assert_eq!($rhs + $lhs, $sum);
1491 let hmsm
= |h
,m
,s
,mi
| NaiveTime
::from_hms_milli(h
, m
, s
, mi
);
1493 check
!(hmsm(3, 5, 7, 900), Duration
::zero(), hmsm(3, 5, 7, 900));
1494 check
!(hmsm(3, 5, 7, 900), Duration
::milliseconds(100), hmsm(3, 5, 8, 0));
1495 check
!(hmsm(3, 5, 7, 1_300), Duration
::milliseconds(-1800), hmsm(3, 5, 6, 500));
1496 check
!(hmsm(3, 5, 7, 1_300), Duration
::milliseconds(-800), hmsm(3, 5, 7, 500));
1497 check
!(hmsm(3, 5, 7, 1_300), Duration
::milliseconds(-100), hmsm(3, 5, 7, 1_200));
1498 check
!(hmsm(3, 5, 7, 1_300), Duration
::milliseconds(100), hmsm(3, 5, 7, 1_400));
1499 check
!(hmsm(3, 5, 7, 1_300), Duration
::milliseconds(800), hmsm(3, 5, 8, 100));
1500 check
!(hmsm(3, 5, 7, 1_300), Duration
::milliseconds(1800), hmsm(3, 5, 9, 100));
1501 check
!(hmsm(3, 5, 7, 900), Duration
::seconds(86399), hmsm(3, 5, 6, 900)); // overwrap
1502 check
!(hmsm(3, 5, 7, 900), Duration
::seconds(-86399), hmsm(3, 5, 8, 900));
1503 check
!(hmsm(3, 5, 7, 900), Duration
::days(12345), hmsm(3, 5, 7, 900));
1504 check
!(hmsm(3, 5, 7, 1_300), Duration
::days(1), hmsm(3, 5, 7, 300));
1505 check
!(hmsm(3, 5, 7, 1_300), Duration
::days(-1), hmsm(3, 5, 8, 300));
1507 // regression tests for #37
1508 check
!(hmsm(0, 0, 0, 0), Duration
::milliseconds(-990), hmsm(23, 59, 59, 10));
1509 check
!(hmsm(0, 0, 0, 0), Duration
::milliseconds(-9990), hmsm(23, 59, 50, 10));
1513 fn test_time_overflowing_add() {
1514 let hmsm
= NaiveTime
::from_hms_milli
;
1516 assert_eq
!(hmsm(3, 4, 5, 678).overflowing_add_signed(Duration
::hours(11)),
1517 (hmsm(14, 4, 5, 678), 0));
1518 assert_eq
!(hmsm(3, 4, 5, 678).overflowing_add_signed(Duration
::hours(23)),
1519 (hmsm(2, 4, 5, 678), 86_400));
1520 assert_eq
!(hmsm(3, 4, 5, 678).overflowing_add_signed(Duration
::hours(-7)),
1521 (hmsm(20, 4, 5, 678), -86_400));
1523 // overflowing_add_signed with leap seconds may be counter-intuitive
1524 assert_eq
!(hmsm(3, 4, 5, 1_678).overflowing_add_signed(Duration
::days(1)),
1525 (hmsm(3, 4, 5, 678), 86_400));
1526 assert_eq
!(hmsm(3, 4, 5, 1_678).overflowing_add_signed(Duration
::days(-1)),
1527 (hmsm(3, 4, 6, 678), -86_400));
1531 fn test_time_addassignment() {
1532 let hms
= NaiveTime
::from_hms
;
1533 let mut time
= hms(12, 12, 12);
1534 time
+= Duration
::hours(10);
1535 assert_eq
!(time
, hms(22, 12, 12));
1536 time
+= Duration
::hours(10);
1537 assert_eq
!(time
, hms(8, 12, 12));
1541 fn test_time_subassignment() {
1542 let hms
= NaiveTime
::from_hms
;
1543 let mut time
= hms(12, 12, 12);
1544 time
-= Duration
::hours(10);
1545 assert_eq
!(time
, hms(2, 12, 12));
1546 time
-= Duration
::hours(10);
1547 assert_eq
!(time
, hms(16, 12, 12));
1551 fn test_time_sub() {
1552 macro_rules
! check
{
1553 ($lhs
:expr
, $rhs
:expr
, $diff
:expr
) => ({
1554 // `time1 - time2 = duration` is equivalent to `time2 - time1 = -duration`
1555 assert_eq
!($lhs
.signed_duration_since($rhs
), $diff
);
1556 assert_eq
!($rhs
.signed_duration_since($lhs
), -$diff
);
1560 let hmsm
= |h
,m
,s
,mi
| NaiveTime
::from_hms_milli(h
, m
, s
, mi
);
1562 check
!(hmsm(3, 5, 7, 900), hmsm(3, 5, 7, 900), Duration
::zero());
1563 check
!(hmsm(3, 5, 7, 900), hmsm(3, 5, 7, 600), Duration
::milliseconds(300));
1564 check
!(hmsm(3, 5, 7, 200), hmsm(2, 4, 6, 200), Duration
::seconds(3600 + 60 + 1));
1565 check
!(hmsm(3, 5, 7, 200), hmsm(2, 4, 6, 300),
1566 Duration
::seconds(3600 + 60) + Duration
::milliseconds(900));
1568 // treats the leap second as if it coincides with the prior non-leap second,
1569 // as required by `time1 - time2 = duration` and `time2 - time1 = -duration` equivalence.
1570 check
!(hmsm(3, 5, 7, 200), hmsm(3, 5, 6, 1_800), Duration
::milliseconds(400));
1571 check
!(hmsm(3, 5, 7, 1_200), hmsm(3, 5, 6, 1_800), Duration
::milliseconds(1400));
1572 check
!(hmsm(3, 5, 7, 1_200), hmsm(3, 5, 6, 800), Duration
::milliseconds(1400));
1574 // additional equality: `time1 + duration = time2` is equivalent to
1575 // `time2 - time1 = duration` IF AND ONLY IF `time2` represents a non-leap second.
1576 assert_eq
!(hmsm(3, 5, 6, 800) + Duration
::milliseconds(400), hmsm(3, 5, 7, 200));
1577 assert_eq
!(hmsm(3, 5, 6, 1_800) + Duration
::milliseconds(400), hmsm(3, 5, 7, 200));
1581 fn test_time_fmt() {
1582 assert_eq
!(format
!("{}", NaiveTime
::from_hms_milli(23, 59, 59, 999)), "23:59:59.999");
1583 assert_eq
!(format
!("{}", NaiveTime
::from_hms_milli(23, 59, 59, 1_000)), "23:59:60");
1584 assert_eq
!(format
!("{}", NaiveTime
::from_hms_milli(23, 59, 59, 1_001)), "23:59:60.001");
1585 assert_eq
!(format
!("{}", NaiveTime
::from_hms_micro(0, 0, 0, 43210)), "00:00:00.043210");
1586 assert_eq
!(format
!("{}", NaiveTime
::from_hms_nano(0, 0, 0, 6543210)), "00:00:00.006543210");
1588 // the format specifier should have no effect on `NaiveTime`
1589 assert_eq
!(format
!("{:30}", NaiveTime
::from_hms_milli(3, 5, 7, 9)), "03:05:07.009");
1593 fn test_date_from_str() {
1602 "23:59:60.373929310237",
1605 let d
= match s
.parse
::<NaiveTime
>() {
1607 Err(e
) => panic
!("parsing `{}` has failed: {}", s
, e
)
1609 let s_
= format
!("{:?}", d
);
1610 // `s` and `s_` may differ, but `s.parse()` and `s_.parse()` must be same
1611 let d_
= match s_
.parse
::<NaiveTime
>() {
1613 Err(e
) => panic
!("`{}` is parsed into `{:?}`, but reparsing that has failed: {}",
1616 assert
!(d
== d_
, "`{}` is parsed into `{:?}`, but reparsed result \
1617 `{:?}` does not match", s
, d
, d_
);
1620 // some invalid cases
1621 // since `ParseErrorKind` is private, all we can do is to check if there was an error
1622 assert
!("".parse
::<NaiveTime
>().is_err());
1623 assert
!("x".parse
::<NaiveTime
>().is_err());
1624 assert
!("15".parse
::<NaiveTime
>().is_err());
1625 assert
!("15:8".parse
::<NaiveTime
>().is_err());
1626 assert
!("15:8:x".parse
::<NaiveTime
>().is_err());
1627 assert
!("15:8:9x".parse
::<NaiveTime
>().is_err());
1628 assert
!("23:59:61".parse
::<NaiveTime
>().is_err());
1629 assert
!("12:34:56.x".parse
::<NaiveTime
>().is_err());
1630 assert
!("12:34:56. 0".parse
::<NaiveTime
>().is_err());
1634 fn test_time_parse_from_str() {
1635 let hms
= |h
,m
,s
| NaiveTime
::from_hms(h
,m
,s
);
1636 assert_eq
!(NaiveTime
::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
1637 Ok(hms(12, 34, 56))); // ignore date and offset
1638 assert_eq
!(NaiveTime
::parse_from_str("PM 12:59", "%P %H:%M"),
1639 Ok(hms(12, 59, 0)));
1640 assert
!(NaiveTime
::parse_from_str("12:3456", "%H:%M:%S").is_err());
1644 fn test_time_format() {
1645 let t
= NaiveTime
::from_hms_nano(3, 5, 7, 98765432);
1646 assert_eq
!(t
.format("%H,%k,%I,%l,%P,%p").to_string(), "03, 3,03, 3,am,AM");
1647 assert_eq
!(t
.format("%M").to_string(), "05");
1648 assert_eq
!(t
.format("%S,%f,%.f").to_string(), "07,098765432,.098765432");
1649 assert_eq
!(t
.format("%.3f,%.6f,%.9f").to_string(), ".098,.098765,.098765432");
1650 assert_eq
!(t
.format("%R").to_string(), "03:05");
1651 assert_eq
!(t
.format("%T,%X").to_string(), "03:05:07,03:05:07");
1652 assert_eq
!(t
.format("%r").to_string(), "03:05:07 AM");
1653 assert_eq
!(t
.format("%t%n%%%n%t").to_string(), "\t\n%\n\t");
1655 let t
= NaiveTime
::from_hms_micro(3, 5, 7, 432100);
1656 assert_eq
!(t
.format("%S,%f,%.f").to_string(), "07,432100000,.432100");
1657 assert_eq
!(t
.format("%.3f,%.6f,%.9f").to_string(), ".432,.432100,.432100000");
1659 let t
= NaiveTime
::from_hms_milli(3, 5, 7, 210);
1660 assert_eq
!(t
.format("%S,%f,%.f").to_string(), "07,210000000,.210");
1661 assert_eq
!(t
.format("%.3f,%.6f,%.9f").to_string(), ".210,.210000,.210000000");
1663 let t
= NaiveTime
::from_hms(3, 5, 7);
1664 assert_eq
!(t
.format("%S,%f,%.f").to_string(), "07,000000000,");
1665 assert_eq
!(t
.format("%.3f,%.6f,%.9f").to_string(), ".000,.000000,.000000000");
1668 assert_eq
!(NaiveTime
::from_hms(13, 57, 9).format("%r").to_string(), "01:57:09 PM");
1669 assert_eq
!(NaiveTime
::from_hms_milli(23, 59, 59, 1_000).format("%X").to_string(),