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