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, Utc};
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_local_timezone(Utc)
93/// .unwrap();
94/// # let _ = (t, dt1, dt2);
95/// ```
96///
97/// Note that the leap second can happen anytime given an appropriate time zone;
98/// 2015-07-01 01:23:60 would be a proper leap second if UTC+01:24 had existed.
99/// Practically speaking, though, by the time of the first leap second on 1972-06-30,
100/// every time zone offset around the world has standardized to the 5-minute alignment.
101///
102/// ## Date And Time Arithmetics
103///
104/// As a concrete example, let's assume that `03:00:60` and `04:00:60` are leap seconds.
105/// In reality, of course, leap seconds are separated by at least 6 months.
106/// We will also use some intuitive concise notations for the explanation.
107///
108/// `Time + TimeDelta`
109/// (short for [`NaiveTime::overflowing_add_signed`](#method.overflowing_add_signed)):
110///
111/// - `03:00:00 + 1s = 03:00:01`.
112/// - `03:00:59 + 60s = 03:01:59`.
113/// - `03:00:59 + 61s = 03:02:00`.
114/// - `03:00:59 + 1s = 03:01:00`.
115/// - `03:00:60 + 1s = 03:01:00`.
116/// Note that the sum is identical to the previous.
117/// - `03:00:60 + 60s = 03:01:59`.
118/// - `03:00:60 + 61s = 03:02:00`.
119/// - `03:00:60.1 + 0.8s = 03:00:60.9`.
120///
121/// `Time - TimeDelta`
122/// (short for [`NaiveTime::overflowing_sub_signed`](#method.overflowing_sub_signed)):
123///
124/// - `03:00:00 - 1s = 02:59:59`.
125/// - `03:01:00 - 1s = 03:00:59`.
126/// - `03:01:00 - 60s = 03:00:00`.
127/// - `03:00:60 - 60s = 03:00:00`.
128/// Note that the result is identical to the previous.
129/// - `03:00:60.7 - 0.4s = 03:00:60.3`.
130/// - `03:00:60.7 - 0.9s = 03:00:59.8`.
131///
132/// `Time - Time`
133/// (short for [`NaiveTime::signed_duration_since`](#method.signed_duration_since)):
134///
135/// - `04:00:00 - 03:00:00 = 3600s`.
136/// - `03:01:00 - 03:00:00 = 60s`.
137/// - `03:00:60 - 03:00:00 = 60s`.
138/// Note that the difference is identical to the previous.
139/// - `03:00:60.6 - 03:00:59.4 = 1.2s`.
140/// - `03:01:00 - 03:00:59.8 = 0.2s`.
141/// - `03:01:00 - 03:00:60.5 = 0.5s`.
142/// Note that the difference is larger than the previous,
143/// even though the leap second clearly follows the previous whole second.
144/// - `04:00:60.9 - 03:00:60.1 =
145/// (04:00:60.9 - 04:00:00) + (04:00:00 - 03:01:00) + (03:01:00 - 03:00:60.1) =
146/// 60.9s + 3540s + 0.9s = 3601.8s`.
147///
148/// In general,
149///
150/// - `Time + TimeDelta` unconditionally equals to `TimeDelta + Time`.
151///
152/// - `Time - TimeDelta` unconditionally equals to `Time + (-TimeDelta)`.
153///
154/// - `Time1 - Time2` unconditionally equals to `-(Time2 - Time1)`.
155///
156/// - Associativity does not generally hold, because
157/// `(Time + TimeDelta1) - TimeDelta2` no longer equals to `Time + (TimeDelta1 - TimeDelta2)`
158/// for two positive durations.
159///
160/// - As a special case, `(Time + TimeDelta) - TimeDelta` also does not equal to `Time`.
161///
162/// - If you can assume that all durations have the same sign, however,
163/// then the associativity holds:
164/// `(Time + TimeDelta1) + TimeDelta2` equals to `Time + (TimeDelta1 + TimeDelta2)`
165/// for two positive durations.
166///
167/// ## Reading And Writing Leap Seconds
168///
169/// The "typical" leap seconds on the minute boundary are
170/// correctly handled both in the formatting and parsing.
171/// The leap second in the human-readable representation
172/// will be represented as the second part being 60, as required by ISO 8601.
173///
174/// ```
175/// use chrono::{NaiveDate, Utc};
176///
177/// let dt = NaiveDate::from_ymd_opt(2015, 6, 30)
178/// .unwrap()
179/// .and_hms_milli_opt(23, 59, 59, 1_000)
180/// .unwrap()
181/// .and_local_timezone(Utc)
182/// .unwrap();
183/// assert_eq!(format!("{:?}", dt), "2015-06-30T23:59:60Z");
184/// ```
185///
186/// There are hypothetical leap seconds not on the minute boundary nevertheless supported by Chrono.
187/// They are allowed for the sake of completeness and consistency; there were several "exotic" time
188/// zone offsets with fractional minutes prior to UTC after all.
189/// For such cases the human-readable representation is ambiguous and would be read back to the next
190/// non-leap second.
191///
192/// A `NaiveTime` with a leap second that is not on a minute boundary can only be created from a
193/// [`DateTime`](crate::DateTime) with fractional minutes as offset, or using
194/// [`Timelike::with_nanosecond()`].
195///
196/// ```
197/// use chrono::{FixedOffset, NaiveDate, TimeZone};
198///
199/// let paramaribo_pre1945 = FixedOffset::east_opt(-13236).unwrap(); // -03:40:36
200/// let leap_sec_2015 =
201/// NaiveDate::from_ymd_opt(2015, 6, 30).unwrap().and_hms_milli_opt(23, 59, 59, 1_000).unwrap();
202/// let dt1 = paramaribo_pre1945.from_utc_datetime(&leap_sec_2015);
203/// assert_eq!(format!("{:?}", dt1), "2015-06-30T20:19:24-03:40:36");
204/// assert_eq!(format!("{:?}", dt1.time()), "20:19:24");
205///
206/// let next_sec = NaiveDate::from_ymd_opt(2015, 7, 1).unwrap().and_hms_opt(0, 0, 0).unwrap();
207/// let dt2 = paramaribo_pre1945.from_utc_datetime(&next_sec);
208/// assert_eq!(format!("{:?}", dt2), "2015-06-30T20:19:24-03:40:36");
209/// assert_eq!(format!("{:?}", dt2.time()), "20:19:24");
210///
211/// assert!(dt1.time() != dt2.time());
212/// assert!(dt1.time().to_string() == dt2.time().to_string());
213/// ```
214///
215/// Since Chrono alone cannot determine any existence of leap seconds,
216/// **there is absolutely no guarantee that the leap second read has actually happened**.
217#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Copy, Clone)]
218#[cfg_attr(
219 any(feature = "rkyv", feature = "rkyv-16", feature = "rkyv-32", feature = "rkyv-64"),
220 derive(Archive, Deserialize, Serialize),
221 archive(compare(PartialEq, PartialOrd)),
222 archive_attr(derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash))
223)]
224#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
225pub struct NaiveTime {
226 secs: u32,
227 frac: u32,
228}
229
230#[cfg(feature = "arbitrary")]
231impl arbitrary::Arbitrary<'_> for NaiveTime {
232 fn arbitrary(u: &mut arbitrary::Unstructured) -> arbitrary::Result<NaiveTime> {
233 let mins = u.int_in_range(0..=1439)?;
234 let mut secs = u.int_in_range(0..=60)?;
235 let mut nano = u.int_in_range(0..=999_999_999)?;
236 if secs == 60 {
237 secs = 59;
238 nano += 1_000_000_000;
239 }
240 let time = NaiveTime::from_num_seconds_from_midnight_opt(mins * 60 + secs, nano)
241 .expect("Could not generate a valid chrono::NaiveTime. It looks like implementation of Arbitrary for NaiveTime is erroneous.");
242 Ok(time)
243 }
244}
245
246impl NaiveTime {
247 /// Makes a new `NaiveTime` from hour, minute and second.
248 ///
249 /// No [leap second](#leap-second-handling) is allowed here;
250 /// use `NaiveTime::from_hms_*` methods with a subsecond parameter instead.
251 ///
252 /// # Panics
253 ///
254 /// Panics on invalid hour, minute and/or second.
255 #[deprecated(since = "0.4.23", note = "use `from_hms_opt()` instead")]
256 #[inline]
257 #[must_use]
258 pub const fn from_hms(hour: u32, min: u32, sec: u32) -> NaiveTime {
259 expect!(NaiveTime::from_hms_opt(hour, min, sec), "invalid time")
260 }
261
262 /// Makes a new `NaiveTime` from hour, minute and second.
263 ///
264 /// The millisecond part is allowed to exceed 1,000,000,000 in order to represent a
265 /// [leap second](#leap-second-handling), but only when `sec == 59`.
266 ///
267 /// # Errors
268 ///
269 /// Returns `None` on invalid hour, minute and/or second.
270 ///
271 /// # Example
272 ///
273 /// ```
274 /// use chrono::NaiveTime;
275 ///
276 /// let from_hms_opt = NaiveTime::from_hms_opt;
277 ///
278 /// assert!(from_hms_opt(0, 0, 0).is_some());
279 /// assert!(from_hms_opt(23, 59, 59).is_some());
280 /// assert!(from_hms_opt(24, 0, 0).is_none());
281 /// assert!(from_hms_opt(23, 60, 0).is_none());
282 /// assert!(from_hms_opt(23, 59, 60).is_none());
283 /// ```
284 #[inline]
285 #[must_use]
286 pub const fn from_hms_opt(hour: u32, min: u32, sec: u32) -> Option<NaiveTime> {
287 NaiveTime::from_hms_nano_opt(hour, min, sec, 0)
288 }
289
290 /// Makes a new `NaiveTime` from hour, minute, second and millisecond.
291 ///
292 /// The millisecond part can exceed 1,000
293 /// in order to represent the [leap second](#leap-second-handling).
294 ///
295 /// # Panics
296 ///
297 /// Panics on invalid hour, minute, second and/or millisecond.
298 #[deprecated(since = "0.4.23", note = "use `from_hms_milli_opt()` instead")]
299 #[inline]
300 #[must_use]
301 pub const fn from_hms_milli(hour: u32, min: u32, sec: u32, milli: u32) -> NaiveTime {
302 expect!(NaiveTime::from_hms_milli_opt(hour, min, sec, milli), "invalid time")
303 }
304
305 /// Makes a new `NaiveTime` from hour, minute, second and millisecond.
306 ///
307 /// The millisecond part is allowed to exceed 1,000,000,000 in order to represent a
308 /// [leap second](#leap-second-handling), but only when `sec == 59`.
309 ///
310 /// # Errors
311 ///
312 /// Returns `None` on invalid hour, minute, second and/or millisecond.
313 ///
314 /// # Example
315 ///
316 /// ```
317 /// use chrono::NaiveTime;
318 ///
319 /// let from_hmsm_opt = NaiveTime::from_hms_milli_opt;
320 ///
321 /// assert!(from_hmsm_opt(0, 0, 0, 0).is_some());
322 /// assert!(from_hmsm_opt(23, 59, 59, 999).is_some());
323 /// assert!(from_hmsm_opt(23, 59, 59, 1_999).is_some()); // a leap second after 23:59:59
324 /// assert!(from_hmsm_opt(24, 0, 0, 0).is_none());
325 /// assert!(from_hmsm_opt(23, 60, 0, 0).is_none());
326 /// assert!(from_hmsm_opt(23, 59, 60, 0).is_none());
327 /// assert!(from_hmsm_opt(23, 59, 59, 2_000).is_none());
328 /// ```
329 #[inline]
330 #[must_use]
331 pub const fn from_hms_milli_opt(
332 hour: u32,
333 min: u32,
334 sec: u32,
335 milli: u32,
336 ) -> Option<NaiveTime> {
337 let nano = try_opt!(milli.checked_mul(1_000_000));
338 NaiveTime::from_hms_nano_opt(hour, min, sec, nano)
339 }
340
341 /// Makes a new `NaiveTime` from hour, minute, second and microsecond.
342 ///
343 /// The microsecond part is allowed to exceed 1,000,000,000 in order to represent a
344 /// [leap second](#leap-second-handling), but only when `sec == 59`.
345 ///
346 /// # Panics
347 ///
348 /// Panics on invalid hour, minute, second and/or microsecond.
349 #[deprecated(since = "0.4.23", note = "use `from_hms_micro_opt()` instead")]
350 #[inline]
351 #[must_use]
352 pub const fn from_hms_micro(hour: u32, min: u32, sec: u32, micro: u32) -> NaiveTime {
353 expect!(NaiveTime::from_hms_micro_opt(hour, min, sec, micro), "invalid time")
354 }
355
356 /// Makes a new `NaiveTime` from hour, minute, second and microsecond.
357 ///
358 /// The microsecond part is allowed to exceed 1,000,000,000 in order to represent a
359 /// [leap second](#leap-second-handling), but only when `sec == 59`.
360 ///
361 /// # Errors
362 ///
363 /// Returns `None` on invalid hour, minute, second and/or microsecond.
364 ///
365 /// # Example
366 ///
367 /// ```
368 /// use chrono::NaiveTime;
369 ///
370 /// let from_hmsu_opt = NaiveTime::from_hms_micro_opt;
371 ///
372 /// assert!(from_hmsu_opt(0, 0, 0, 0).is_some());
373 /// assert!(from_hmsu_opt(23, 59, 59, 999_999).is_some());
374 /// assert!(from_hmsu_opt(23, 59, 59, 1_999_999).is_some()); // a leap second after 23:59:59
375 /// assert!(from_hmsu_opt(24, 0, 0, 0).is_none());
376 /// assert!(from_hmsu_opt(23, 60, 0, 0).is_none());
377 /// assert!(from_hmsu_opt(23, 59, 60, 0).is_none());
378 /// assert!(from_hmsu_opt(23, 59, 59, 2_000_000).is_none());
379 /// ```
380 #[inline]
381 #[must_use]
382 pub const fn from_hms_micro_opt(
383 hour: u32,
384 min: u32,
385 sec: u32,
386 micro: u32,
387 ) -> Option<NaiveTime> {
388 let nano = try_opt!(micro.checked_mul(1_000));
389 NaiveTime::from_hms_nano_opt(hour, min, sec, nano)
390 }
391
392 /// Makes a new `NaiveTime` from hour, minute, second and nanosecond.
393 ///
394 /// The nanosecond part is allowed to exceed 1,000,000,000 in order to represent a
395 /// [leap second](#leap-second-handling), but only when `sec == 59`.
396 ///
397 /// # Panics
398 ///
399 /// Panics on invalid hour, minute, second and/or nanosecond.
400 #[deprecated(since = "0.4.23", note = "use `from_hms_nano_opt()` instead")]
401 #[inline]
402 #[must_use]
403 pub const fn from_hms_nano(hour: u32, min: u32, sec: u32, nano: u32) -> NaiveTime {
404 expect!(NaiveTime::from_hms_nano_opt(hour, min, sec, nano), "invalid time")
405 }
406
407 /// Makes a new `NaiveTime` from hour, minute, second and nanosecond.
408 ///
409 /// The nanosecond part is allowed to exceed 1,000,000,000 in order to represent a
410 /// [leap second](#leap-second-handling), but only when `sec == 59`.
411 ///
412 /// # Errors
413 ///
414 /// Returns `None` on invalid hour, minute, second and/or nanosecond.
415 ///
416 /// # Example
417 ///
418 /// ```
419 /// use chrono::NaiveTime;
420 ///
421 /// let from_hmsn_opt = NaiveTime::from_hms_nano_opt;
422 ///
423 /// assert!(from_hmsn_opt(0, 0, 0, 0).is_some());
424 /// assert!(from_hmsn_opt(23, 59, 59, 999_999_999).is_some());
425 /// assert!(from_hmsn_opt(23, 59, 59, 1_999_999_999).is_some()); // a leap second after 23:59:59
426 /// assert!(from_hmsn_opt(24, 0, 0, 0).is_none());
427 /// assert!(from_hmsn_opt(23, 60, 0, 0).is_none());
428 /// assert!(from_hmsn_opt(23, 59, 60, 0).is_none());
429 /// assert!(from_hmsn_opt(23, 59, 59, 2_000_000_000).is_none());
430 /// ```
431 #[inline]
432 #[must_use]
433 pub const fn from_hms_nano_opt(hour: u32, min: u32, sec: u32, nano: u32) -> Option<NaiveTime> {
434 if (hour >= 24 || min >= 60 || sec >= 60)
435 || (nano >= 1_000_000_000 && sec != 59)
436 || nano >= 2_000_000_000
437 {
438 return None;
439 }
440 let secs = hour * 3600 + min * 60 + sec;
441 Some(NaiveTime { secs, frac: nano })
442 }
443
444 /// Makes a new `NaiveTime` from the number of seconds since midnight and nanosecond.
445 ///
446 /// The nanosecond part is allowed to exceed 1,000,000,000 in order to represent a
447 /// [leap second](#leap-second-handling), but only when `secs % 60 == 59`.
448 ///
449 /// # Panics
450 ///
451 /// Panics on invalid number of seconds and/or nanosecond.
452 #[deprecated(since = "0.4.23", note = "use `from_num_seconds_from_midnight_opt()` instead")]
453 #[inline]
454 #[must_use]
455 pub const fn from_num_seconds_from_midnight(secs: u32, nano: u32) -> NaiveTime {
456 expect!(NaiveTime::from_num_seconds_from_midnight_opt(secs, nano), "invalid time")
457 }
458
459 /// Makes a new `NaiveTime` from the number of seconds since midnight and nanosecond.
460 ///
461 /// The nanosecond part is allowed to exceed 1,000,000,000 in order to represent a
462 /// [leap second](#leap-second-handling), but only when `secs % 60 == 59`.
463 ///
464 /// # Errors
465 ///
466 /// Returns `None` on invalid number of seconds and/or nanosecond.
467 ///
468 /// # Example
469 ///
470 /// ```
471 /// use chrono::NaiveTime;
472 ///
473 /// let from_nsecs_opt = NaiveTime::from_num_seconds_from_midnight_opt;
474 ///
475 /// assert!(from_nsecs_opt(0, 0).is_some());
476 /// assert!(from_nsecs_opt(86399, 999_999_999).is_some());
477 /// assert!(from_nsecs_opt(86399, 1_999_999_999).is_some()); // a leap second after 23:59:59
478 /// assert!(from_nsecs_opt(86_400, 0).is_none());
479 /// assert!(from_nsecs_opt(86399, 2_000_000_000).is_none());
480 /// ```
481 #[inline]
482 #[must_use]
483 pub const fn from_num_seconds_from_midnight_opt(secs: u32, nano: u32) -> Option<NaiveTime> {
484 if secs >= 86_400 || nano >= 2_000_000_000 || (nano >= 1_000_000_000 && secs % 60 != 59) {
485 return None;
486 }
487 Some(NaiveTime { secs, frac: nano })
488 }
489
490 /// Parses a string with the specified format string and returns a new `NaiveTime`.
491 /// See the [`format::strftime` module](crate::format::strftime)
492 /// on the supported escape sequences.
493 ///
494 /// # Example
495 ///
496 /// ```
497 /// use chrono::NaiveTime;
498 ///
499 /// let parse_from_str = NaiveTime::parse_from_str;
500 ///
501 /// assert_eq!(
502 /// parse_from_str("23:56:04", "%H:%M:%S"),
503 /// Ok(NaiveTime::from_hms_opt(23, 56, 4).unwrap())
504 /// );
505 /// assert_eq!(
506 /// parse_from_str("pm012345.6789", "%p%I%M%S%.f"),
507 /// Ok(NaiveTime::from_hms_micro_opt(13, 23, 45, 678_900).unwrap())
508 /// );
509 /// ```
510 ///
511 /// Date and offset is ignored for the purpose of parsing.
512 ///
513 /// ```
514 /// # use chrono::NaiveTime;
515 /// # let parse_from_str = NaiveTime::parse_from_str;
516 /// assert_eq!(
517 /// parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
518 /// Ok(NaiveTime::from_hms_opt(12, 34, 56).unwrap())
519 /// );
520 /// ```
521 ///
522 /// [Leap seconds](#leap-second-handling) are correctly handled by
523 /// treating any time of the form `hh:mm:60` as a leap second.
524 /// (This equally applies to the formatting, so the round trip is possible.)
525 ///
526 /// ```
527 /// # use chrono::NaiveTime;
528 /// # let parse_from_str = NaiveTime::parse_from_str;
529 /// assert_eq!(
530 /// parse_from_str("08:59:60.123", "%H:%M:%S%.f"),
531 /// Ok(NaiveTime::from_hms_milli_opt(8, 59, 59, 1_123).unwrap())
532 /// );
533 /// ```
534 ///
535 /// Missing seconds are assumed to be zero,
536 /// but out-of-bound times or insufficient fields are errors otherwise.
537 ///
538 /// ```
539 /// # use chrono::NaiveTime;
540 /// # let parse_from_str = NaiveTime::parse_from_str;
541 /// assert_eq!(parse_from_str("7:15", "%H:%M"), Ok(NaiveTime::from_hms_opt(7, 15, 0).unwrap()));
542 ///
543 /// assert!(parse_from_str("04m33s", "%Mm%Ss").is_err());
544 /// assert!(parse_from_str("12", "%H").is_err());
545 /// assert!(parse_from_str("17:60", "%H:%M").is_err());
546 /// assert!(parse_from_str("24:00:00", "%H:%M:%S").is_err());
547 /// ```
548 ///
549 /// All parsed fields should be consistent to each other, otherwise it's an error.
550 /// Here `%H` is for 24-hour clocks, unlike `%I`,
551 /// and thus can be independently determined without AM/PM.
552 ///
553 /// ```
554 /// # use chrono::NaiveTime;
555 /// # let parse_from_str = NaiveTime::parse_from_str;
556 /// assert!(parse_from_str("13:07 AM", "%H:%M %p").is_err());
557 /// ```
558 pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveTime> {
559 let mut parsed = Parsed::new();
560 parse(&mut parsed, s, StrftimeItems::new(fmt))?;
561 parsed.to_naive_time()
562 }
563
564 /// Parses a string from a user-specified format into a new `NaiveTime` value, and a slice with
565 /// the remaining portion of the string.
566 /// See the [`format::strftime` module](crate::format::strftime)
567 /// on the supported escape sequences.
568 ///
569 /// Similar to [`parse_from_str`](#method.parse_from_str).
570 ///
571 /// # Example
572 ///
573 /// ```rust
574 /// # use chrono::{NaiveTime};
575 /// let (time, remainder) =
576 /// NaiveTime::parse_and_remainder("3h4m33s trailing text", "%-Hh%-Mm%-Ss").unwrap();
577 /// assert_eq!(time, NaiveTime::from_hms_opt(3, 4, 33).unwrap());
578 /// assert_eq!(remainder, " trailing text");
579 /// ```
580 pub fn parse_and_remainder<'a>(s: &'a str, fmt: &str) -> ParseResult<(NaiveTime, &'a str)> {
581 let mut parsed = Parsed::new();
582 let remainder = parse_and_remainder(&mut parsed, s, StrftimeItems::new(fmt))?;
583 parsed.to_naive_time().map(|t| (t, remainder))
584 }
585
586 /// Adds given `TimeDelta` to the current time, and also returns the number of *seconds*
587 /// in the integral number of days ignored from the addition.
588 ///
589 /// # Example
590 ///
591 /// ```
592 /// use chrono::{NaiveTime, TimeDelta};
593 ///
594 /// let from_hms = |h, m, s| NaiveTime::from_hms_opt(h, m, s).unwrap();
595 ///
596 /// assert_eq!(
597 /// from_hms(3, 4, 5).overflowing_add_signed(TimeDelta::try_hours(11).unwrap()),
598 /// (from_hms(14, 4, 5), 0)
599 /// );
600 /// assert_eq!(
601 /// from_hms(3, 4, 5).overflowing_add_signed(TimeDelta::try_hours(23).unwrap()),
602 /// (from_hms(2, 4, 5), 86_400)
603 /// );
604 /// assert_eq!(
605 /// from_hms(3, 4, 5).overflowing_add_signed(TimeDelta::try_hours(-7).unwrap()),
606 /// (from_hms(20, 4, 5), -86_400)
607 /// );
608 /// ```
609 #[must_use]
610 pub const fn overflowing_add_signed(&self, rhs: TimeDelta) -> (NaiveTime, i64) {
611 let mut secs = self.secs as i64;
612 let mut frac = self.frac as i32;
613 let secs_to_add = rhs.num_seconds();
614 let frac_to_add = rhs.subsec_nanos();
615
616 // Check if `self` is a leap second and adding `rhs` would escape that leap second.
617 // If that is the case, update `frac` and `secs` to involve no leap second.
618 // If it stays within the leap second or the second before, and only adds a fractional
619 // second, just do that and return (this way the rest of the code can ignore leap seconds).
620 if frac >= 1_000_000_000 {
621 // check below is adjusted to not overflow an i32: `frac + frac_to_add >= 2_000_000_000`
622 if secs_to_add > 0 || (frac_to_add > 0 && frac >= 2_000_000_000 - frac_to_add) {
623 frac -= 1_000_000_000;
624 } else if secs_to_add < 0 {
625 frac -= 1_000_000_000;
626 secs += 1;
627 } else {
628 return (NaiveTime { secs: self.secs, frac: (frac + frac_to_add) as u32 }, 0);
629 }
630 }
631
632 let mut secs = secs + secs_to_add;
633 frac += frac_to_add;
634
635 if frac < 0 {
636 frac += 1_000_000_000;
637 secs -= 1;
638 } else if frac >= 1_000_000_000 {
639 frac -= 1_000_000_000;
640 secs += 1;
641 }
642
643 let secs_in_day = secs.rem_euclid(86_400);
644 let remaining = secs - secs_in_day;
645 (NaiveTime { secs: secs_in_day as u32, frac: frac as u32 }, remaining)
646 }
647
648 /// Subtracts given `TimeDelta` from the current time, and also returns the number of *seconds*
649 /// in the integral number of days ignored from the subtraction.
650 ///
651 /// # Example
652 ///
653 /// ```
654 /// use chrono::{NaiveTime, TimeDelta};
655 ///
656 /// let from_hms = |h, m, s| NaiveTime::from_hms_opt(h, m, s).unwrap();
657 ///
658 /// assert_eq!(
659 /// from_hms(3, 4, 5).overflowing_sub_signed(TimeDelta::try_hours(2).unwrap()),
660 /// (from_hms(1, 4, 5), 0)
661 /// );
662 /// assert_eq!(
663 /// from_hms(3, 4, 5).overflowing_sub_signed(TimeDelta::try_hours(17).unwrap()),
664 /// (from_hms(10, 4, 5), 86_400)
665 /// );
666 /// assert_eq!(
667 /// from_hms(3, 4, 5).overflowing_sub_signed(TimeDelta::try_hours(-22).unwrap()),
668 /// (from_hms(1, 4, 5), -86_400)
669 /// );
670 /// ```
671 #[inline]
672 #[must_use]
673 pub const fn overflowing_sub_signed(&self, rhs: TimeDelta) -> (NaiveTime, i64) {
674 let (time, rhs) = self.overflowing_add_signed(rhs.neg());
675 (time, -rhs) // safe to negate, rhs is within +/- (2^63 / 1000)
676 }
677
678 /// Subtracts another `NaiveTime` from the current time.
679 /// Returns a `TimeDelta` within +/- 1 day.
680 /// This does not overflow or underflow at all.
681 ///
682 /// As a part of Chrono's [leap second handling](#leap-second-handling),
683 /// the subtraction assumes that **there is no leap second ever**,
684 /// except when any of the `NaiveTime`s themselves represents a leap second
685 /// in which case the assumption becomes that
686 /// **there are exactly one (or two) leap second(s) ever**.
687 ///
688 /// # Example
689 ///
690 /// ```
691 /// use chrono::{NaiveTime, TimeDelta};
692 ///
693 /// let from_hmsm = |h, m, s, milli| NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap();
694 /// let since = NaiveTime::signed_duration_since;
695 ///
696 /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 7, 900)), TimeDelta::zero());
697 /// assert_eq!(
698 /// since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 7, 875)),
699 /// TimeDelta::try_milliseconds(25).unwrap()
700 /// );
701 /// assert_eq!(
702 /// since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 6, 925)),
703 /// TimeDelta::try_milliseconds(975).unwrap()
704 /// );
705 /// assert_eq!(
706 /// since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 0, 900)),
707 /// TimeDelta::try_seconds(7).unwrap()
708 /// );
709 /// assert_eq!(
710 /// since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 0, 7, 900)),
711 /// TimeDelta::try_seconds(5 * 60).unwrap()
712 /// );
713 /// assert_eq!(
714 /// since(from_hmsm(3, 5, 7, 900), from_hmsm(0, 5, 7, 900)),
715 /// TimeDelta::try_seconds(3 * 3600).unwrap()
716 /// );
717 /// assert_eq!(
718 /// since(from_hmsm(3, 5, 7, 900), from_hmsm(4, 5, 7, 900)),
719 /// TimeDelta::try_seconds(-3600).unwrap()
720 /// );
721 /// assert_eq!(
722 /// since(from_hmsm(3, 5, 7, 900), from_hmsm(2, 4, 6, 800)),
723 /// TimeDelta::try_seconds(3600 + 60 + 1).unwrap() + TimeDelta::try_milliseconds(100).unwrap()
724 /// );
725 /// ```
726 ///
727 /// Leap seconds are handled, but the subtraction assumes that
728 /// there were no other leap seconds happened.
729 ///
730 /// ```
731 /// # use chrono::{TimeDelta, NaiveTime};
732 /// # let from_hmsm = |h, m, s, milli| { NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap() };
733 /// # let since = NaiveTime::signed_duration_since;
734 /// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(3, 0, 59, 0)),
735 /// TimeDelta::try_seconds(1).unwrap());
736 /// assert_eq!(since(from_hmsm(3, 0, 59, 1_500), from_hmsm(3, 0, 59, 0)),
737 /// TimeDelta::try_milliseconds(1500).unwrap());
738 /// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(3, 0, 0, 0)),
739 /// TimeDelta::try_seconds(60).unwrap());
740 /// assert_eq!(since(from_hmsm(3, 0, 0, 0), from_hmsm(2, 59, 59, 1_000)),
741 /// TimeDelta::try_seconds(1).unwrap());
742 /// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(2, 59, 59, 1_000)),
743 /// TimeDelta::try_seconds(61).unwrap());
744 /// ```
745 #[must_use]
746 pub const fn signed_duration_since(self, rhs: NaiveTime) -> TimeDelta {
747 // | | :leap| | | | | | | :leap| |
748 // | | : | | | | | | | : | |
749 // ----+----+-----*---+----+----+----+----+----+----+-------*-+----+----
750 // | `rhs` | | `self`
751 // |======================================>| |
752 // | | `self.secs - rhs.secs` |`self.frac`
753 // |====>| | |======>|
754 // `rhs.frac`|========================================>|
755 // | | | `self - rhs` | |
756
757 let mut secs = self.secs as i64 - rhs.secs as i64;
758 let frac = self.frac as i64 - rhs.frac as i64;
759
760 // `secs` may contain a leap second yet to be counted
761 if self.secs > rhs.secs && rhs.frac >= 1_000_000_000 {
762 secs += 1;
763 } else if self.secs < rhs.secs && self.frac >= 1_000_000_000 {
764 secs -= 1;
765 }
766
767 let secs_from_frac = frac.div_euclid(1_000_000_000);
768 let frac = frac.rem_euclid(1_000_000_000) as u32;
769
770 expect!(TimeDelta::new(secs + secs_from_frac, frac), "must be in range")
771 }
772
773 /// Adds given `FixedOffset` to the current time, and returns the number of days that should be
774 /// added to a date as a result of the offset (either `-1`, `0`, or `1` because the offset is
775 /// always less than 24h).
776 ///
777 /// This method is similar to [`overflowing_add_signed`](#method.overflowing_add_signed), but
778 /// preserves leap seconds.
779 pub(super) const fn overflowing_add_offset(&self, offset: FixedOffset) -> (NaiveTime, i32) {
780 let secs = self.secs as i32 + offset.local_minus_utc();
781 let days = secs.div_euclid(86_400);
782 let secs = secs.rem_euclid(86_400);
783 (NaiveTime { secs: secs as u32, frac: self.frac }, days)
784 }
785
786 /// Subtracts given `FixedOffset` from the current time, and returns the number of days that
787 /// should be added to a date as a result of the offset (either `-1`, `0`, or `1` because the
788 /// offset is always less than 24h).
789 ///
790 /// This method is similar to [`overflowing_sub_signed`](#method.overflowing_sub_signed), but
791 /// preserves leap seconds.
792 pub(super) const fn overflowing_sub_offset(&self, offset: FixedOffset) -> (NaiveTime, i32) {
793 let secs = self.secs as i32 - offset.local_minus_utc();
794 let days = secs.div_euclid(86_400);
795 let secs = secs.rem_euclid(86_400);
796 (NaiveTime { secs: secs as u32, frac: self.frac }, days)
797 }
798
799 /// Formats the time with the specified formatting items.
800 /// Otherwise it is the same as the ordinary [`format`](#method.format) method.
801 ///
802 /// The `Iterator` of items should be `Clone`able,
803 /// since the resulting `DelayedFormat` value may be formatted multiple times.
804 ///
805 /// # Example
806 ///
807 /// ```
808 /// use chrono::format::strftime::StrftimeItems;
809 /// use chrono::NaiveTime;
810 ///
811 /// let fmt = StrftimeItems::new("%H:%M:%S");
812 /// let t = NaiveTime::from_hms_opt(23, 56, 4).unwrap();
813 /// assert_eq!(t.format_with_items(fmt.clone()).to_string(), "23:56:04");
814 /// assert_eq!(t.format("%H:%M:%S").to_string(), "23:56:04");
815 /// ```
816 ///
817 /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
818 ///
819 /// ```
820 /// # use chrono::NaiveTime;
821 /// # use chrono::format::strftime::StrftimeItems;
822 /// # let fmt = StrftimeItems::new("%H:%M:%S").clone();
823 /// # let t = NaiveTime::from_hms_opt(23, 56, 4).unwrap();
824 /// assert_eq!(format!("{}", t.format_with_items(fmt)), "23:56:04");
825 /// ```
826 #[cfg(feature = "alloc")]
827 #[inline]
828 #[must_use]
829 pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat<I>
830 where
831 I: Iterator<Item = B> + Clone,
832 B: Borrow<Item<'a>>,
833 {
834 DelayedFormat::new(None, Some(*self), items)
835 }
836
837 /// Formats the time with the specified format string.
838 /// See the [`format::strftime` module](crate::format::strftime)
839 /// on the supported escape sequences.
840 ///
841 /// This returns a `DelayedFormat`,
842 /// which gets converted to a string only when actual formatting happens.
843 /// You may use the `to_string` method to get a `String`,
844 /// or just feed it into `print!` and other formatting macros.
845 /// (In this way it avoids the redundant memory allocation.)
846 ///
847 /// A wrong format string does *not* issue an error immediately.
848 /// Rather, converting or formatting the `DelayedFormat` fails.
849 /// You are recommended to immediately use `DelayedFormat` for this reason.
850 ///
851 /// # Example
852 ///
853 /// ```
854 /// use chrono::NaiveTime;
855 ///
856 /// let t = NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap();
857 /// assert_eq!(t.format("%H:%M:%S").to_string(), "23:56:04");
858 /// assert_eq!(t.format("%H:%M:%S%.6f").to_string(), "23:56:04.012345");
859 /// assert_eq!(t.format("%-I:%M %p").to_string(), "11:56 PM");
860 /// ```
861 ///
862 /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
863 ///
864 /// ```
865 /// # use chrono::NaiveTime;
866 /// # let t = NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap();
867 /// assert_eq!(format!("{}", t.format("%H:%M:%S")), "23:56:04");
868 /// assert_eq!(format!("{}", t.format("%H:%M:%S%.6f")), "23:56:04.012345");
869 /// assert_eq!(format!("{}", t.format("%-I:%M %p")), "11:56 PM");
870 /// ```
871 #[cfg(feature = "alloc")]
872 #[inline]
873 #[must_use]
874 pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
875 self.format_with_items(StrftimeItems::new(fmt))
876 }
877
878 /// Returns a triple of the hour, minute and second numbers.
879 pub(crate) fn hms(&self) -> (u32, u32, u32) {
880 let sec = self.secs % 60;
881 let mins = self.secs / 60;
882 let min = mins % 60;
883 let hour = mins / 60;
884 (hour, min, sec)
885 }
886
887 /// Returns the number of non-leap seconds past the last midnight.
888 // This duplicates `Timelike::num_seconds_from_midnight()`, because trait methods can't be const
889 // yet.
890 #[inline]
891 pub(crate) const fn num_seconds_from_midnight(&self) -> u32 {
892 self.secs
893 }
894
895 /// Returns the number of nanoseconds since the whole non-leap second.
896 // This duplicates `Timelike::nanosecond()`, because trait methods can't be const yet.
897 #[inline]
898 pub(crate) const fn nanosecond(&self) -> u32 {
899 self.frac
900 }
901
902 /// The earliest possible `NaiveTime`
903 pub const MIN: Self = Self { secs: 0, frac: 0 };
904 pub(super) const MAX: Self = Self { secs: 23 * 3600 + 59 * 60 + 59, frac: 999_999_999 };
905}
906
907impl Timelike for NaiveTime {
908 /// Returns the hour number from 0 to 23.
909 ///
910 /// # Example
911 ///
912 /// ```
913 /// use chrono::{NaiveTime, Timelike};
914 ///
915 /// assert_eq!(NaiveTime::from_hms_opt(0, 0, 0).unwrap().hour(), 0);
916 /// assert_eq!(NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap().hour(), 23);
917 /// ```
918 #[inline]
919 fn hour(&self) -> u32 {
920 self.hms().0
921 }
922
923 /// Returns the minute number from 0 to 59.
924 ///
925 /// # Example
926 ///
927 /// ```
928 /// use chrono::{NaiveTime, Timelike};
929 ///
930 /// assert_eq!(NaiveTime::from_hms_opt(0, 0, 0).unwrap().minute(), 0);
931 /// assert_eq!(NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap().minute(), 56);
932 /// ```
933 #[inline]
934 fn minute(&self) -> u32 {
935 self.hms().1
936 }
937
938 /// Returns the second number from 0 to 59.
939 ///
940 /// # Example
941 ///
942 /// ```
943 /// use chrono::{NaiveTime, Timelike};
944 ///
945 /// assert_eq!(NaiveTime::from_hms_opt(0, 0, 0).unwrap().second(), 0);
946 /// assert_eq!(NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap().second(), 4);
947 /// ```
948 ///
949 /// This method never returns 60 even when it is a leap second.
950 /// ([Why?](#leap-second-handling))
951 /// Use the proper [formatting method](#method.format) to get a human-readable representation.
952 ///
953 #[cfg_attr(not(feature = "std"), doc = "```ignore")]
954 #[cfg_attr(feature = "std", doc = "```")]
955 /// # use chrono::{NaiveTime, Timelike};
956 /// let leap = NaiveTime::from_hms_milli_opt(23, 59, 59, 1_000).unwrap();
957 /// assert_eq!(leap.second(), 59);
958 /// assert_eq!(leap.format("%H:%M:%S").to_string(), "23:59:60");
959 /// ```
960 #[inline]
961 fn second(&self) -> u32 {
962 self.hms().2
963 }
964
965 /// Returns the number of nanoseconds since the whole non-leap second.
966 /// The range from 1,000,000,000 to 1,999,999,999 represents
967 /// the [leap second](#leap-second-handling).
968 ///
969 /// # Example
970 ///
971 /// ```
972 /// use chrono::{NaiveTime, Timelike};
973 ///
974 /// assert_eq!(NaiveTime::from_hms_opt(0, 0, 0).unwrap().nanosecond(), 0);
975 /// assert_eq!(
976 /// NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap().nanosecond(),
977 /// 12_345_678
978 /// );
979 /// ```
980 ///
981 /// Leap seconds may have seemingly out-of-range return values.
982 /// You can reduce the range with `time.nanosecond() % 1_000_000_000`, or
983 /// use the proper [formatting method](#method.format) to get a human-readable representation.
984 ///
985 #[cfg_attr(not(feature = "std"), doc = "```ignore")]
986 #[cfg_attr(feature = "std", doc = "```")]
987 /// # use chrono::{NaiveTime, Timelike};
988 /// let leap = NaiveTime::from_hms_milli_opt(23, 59, 59, 1_000).unwrap();
989 /// assert_eq!(leap.nanosecond(), 1_000_000_000);
990 /// assert_eq!(leap.format("%H:%M:%S%.9f").to_string(), "23:59:60.000000000");
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: u64 = rhs.as_secs() % (2 * 24 * 60 * 60);
1242 let d: TimeDelta = 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: u64 = rhs.as_secs() % (2 * 24 * 60 * 60);
1364 let d: TimeDelta = 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(hour:0, min:0, sec: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}
1743