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