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