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