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