T15:20:00.000000123", ); ``` # What is "civil" time? A civil datetime is a calendar date and a clock time. It also goes by the names "naive," "local" or "plain." The most important thing to understand about civil time is that it does not correspond to a precise instant in time. This is in contrast to types like [`Timestamp`](crate::Timestamp) and [`Zoned`](crate::Zoned), which _do_ correspond to a precise instant in time (to nanosecond precision). Because a civil datetime _never_ has a time zone associated with it, and because some time zones have transitions that skip or repeat clock times, it follows that not all civil datetimes precisely map to a single instant in time. For example, `2024-03-10 02:30` never existed on a clock in `America/New_York` because the 2 o'clock hour was skipped when the clocks were "moved forward" for daylight saving time. Conversely, `2024-11-03 01:30` occurred twice in `America/New_York` because the 1 o'clock hour was repeated when clocks were "moved backward" for daylight saving time. (When time is skipped, it's called a "gap." When time is repeated, it's called a "fold.") In contrast, an instant in time (that is, `Timestamp` or `Zoned`) can _always_ be converted to a civil datetime. And, when a civil datetime is combined with its time zone identifier _and_ its offset, the resulting machine readable string is unambiguous 100% of the time: ``` use jiff::{civil::date, tz::TimeZone}; let tz = TimeZone::get("America/New_York")?; let dt = date(2024, 11, 3).at(1, 30, 0, 0); // It's ambiguous, so asking for an unambiguous instant presents an error! assert!(tz.to_ambiguous_zoned(dt).unambiguous().is_err()); // Gives you the earlier time in a fold, i.e., before DST ends: assert_eq!( tz.to_ambiguous_zoned(dt).earlier()?.to_string(), "2024-11-03T01:30:00-04:00[America/New_York]", ); // Gives you the later time in a fold, i.e., after DST ends. // Notice the offset change from the previous example! assert_eq!( tz.to_ambiguous_zoned(dt).later()?.to_string(), "2024-11-03T01:30:00-05:00[America/New_York]", ); // "Just give me something reasonable" assert_eq!( tz.to_ambiguous_zoned(dt).compatible()?.to_string(), "2024-11-03T01:30:00-04:00[America/New_York]", ); # Ok::<(), Box>(()) ``` # When should I use civil time? Here is a likely non-exhaustive list of reasons why you might want to use civil time: * When you want or need to deal with calendar and clock units as an intermediate step before and/or after associating it with a time zone. For example, perhaps you need to parse strings like `2000-01-01T00:00:00` from a CSV file that have no time zone or offset information, but the time zone is implied through some out-of-band mechanism. * When time zone is actually irrelevant. For example, a fitness tracking app that reminds you to work-out at 6am local time, regardless of which time zone you're in. * When you need to perform arithmetic that deliberately ignores daylight saving time. * When interacting with legacy systems or systems that specifically do not support time zones. */ITimeITimeNanosecondITimeSecondCivilDayNanosecondCivilDaySecondMicrosecondMillisecondSubsecNanosecond/// A representation of civil "wall clock" time./// Conceptually, a `Time` value corresponds to the typical hours and minutes/// that you might see on a clock. This type also contains the second and/// fractional subsecond (to nanosecond precision) associated with a time./// # Civil time/// A `Time` value behaves as if it corresponds precisely to a single/// nanosecond within a day, where all days have `86,400` seconds. That is,/// any given `Time` value corresponds to a nanosecond in the inclusive range/// `[0, 86399999999999]`, where `0` corresponds to `00:00:00.000000000`/// ([`Time::MIN`]) and `86399999999999` corresponds to `23:59:59.999999999`/// ([`Time::MAX`]). Moreover, in civil time, all hours have the same number of/// minutes, all minutes have the same number of seconds and all seconds have/// the same number of nanoseconds./// The `Time` type provides convenient trait implementations of/// let t: Time = "15:22:45".parse()?;/// assert_eq!(t.to_string(), "15:22:45");/// A civil `Time` can also be parsed from something that _contains_ a/// time, but with perhaps other data (such as an offset or time zone):/// let t: Time = "2024-06-19T15:22:45-04[America/New_York]".parse()?;/// value is midnight. i.e., `00:00:00.000000000`./// The only exception is that if one parses a time with a second component/// use jiff::civil::{Time, time};/// let t: Time = "23:59:60".parse()?;/// assert_eq!(t, time(23, 59, 59, 0));/// The `Time` type provides both `Eq` and `Ord` trait implementations to/// facilitate easy comparisons. When a time `t1` occurs before a time `t2`,/// then `t1 < t2`. For example:/// let t1 = time(7, 30, 1, 0);/// let t2 = time(8, 10, 0, 0);/// assert!(t1 < t2);/// As mentioned above, `Time` values are not associated with timezones, and/// thus transitions such as DST are not taken into account when comparing/// `Time` values./// well as computing the span of time between two `Time` values./// * [`Time::wrapping_add`] or [`Time::wrapping_sub`] for wrapping arithmetic./// * [`Time::checked_add`] or [`Time::checked_sub`] for checked arithmetic./// * [`Time::saturating_add`] or [`Time::saturating_sub`] for saturating/// Additionally, wrapping arithmetic is available via the `Add` and `Sub`/// trait implementations:/// use jiff::{civil::time, ToSpan};/// let t = time(20, 10, 1, 0);/// let span = 1.hours().minutes(49).seconds(59);/// assert_eq!(t + span, time(22, 0, 0, 0));/// // Overflow will result in wrap-around unless using checked/// // arithmetic explicitly./// let t = time(23, 59, 59, 999_999_999);/// assert_eq!(time(0, 0, 0, 0), t + 1.nanoseconds());/// Wrapping arithmetic is used by default because it corresponds to how clocks/// showing the time of day behave in practice./// One can compute the span of time between two times using either/// [`Time::until`] or [`Time::since`]. It's also possible to subtract two/// `Time` values directly via a `Sub` trait implementation:/// let time1 = time(22, 0, 0, 0);/// let time2 = time(20, 10, 1, 0);/// time1 - time2,/// 1.hours().minutes(49).seconds(59).fieldwise(),/// rounding the span returned. For example, the default largest unit is hours/// (as exemplified above), but we can ask for smaller units:/// use jiff::{civil::time, ToSpan, Unit};/// let time1 = time(23, 30, 0, 0);/// let time2 = time(7, 0, 0, 0);/// time1.since((Unit::Minute, time2))?,/// 990.minutes().fieldwise(),/// use jiff::{civil::{TimeDifference, time}, RoundMode, ToSpan, Unit};/// let time2 = time(23, 35, 59, 0);/// time1.until(/// TimeDifference::new(time2).smallest(Unit::Minute),/// 5.minutes().fieldwise(),/// // `TimeDifference` uses truncation as a rounding mode by default,/// TimeDifference::new(time2)/// // Rounds up to 6 minutes./// 6.minutes().fieldwise(),/// A `Time` can be rounded based on a [`TimeRound`] configuration of smallest/// units, rounding increment and rounding mode. Here's an example showing how/// to round to the nearest third hour:/// use jiff::{civil::{TimeRound, time}, Unit};/// let t = time(16, 27, 29, 999_999_999);/// t.round(TimeRound::new().smallest(Unit::Hour).increment(3))?,/// time(15, 0, 0, 0),/// // Or alternatively, make use of the `From<(Unit, i64)> for TimeRound`/// assert_eq!(t.round((Unit::Hour, 3))?, time(15, 0, 0, 0));/// See [`Time::round`] for more details./// The minimum representable time value./// This corresponds to `00:00:00.000000000`./// The maximum representable time value./// This corresponds to `23:59:59.999999999`./// Creates a new `Time` value from its component hour, minute, second and/// fractional subsecond (up to nanosecond precision) values./// To set the component values of a time after creating it, use/// [`TimeWith`] via [`Time::with`] to build a new [`Time`] from the fields/// of an existing time./// This returns an error unless *all* of the following conditions are/// This shows an example of a valid time:/// let t = Time::new(21, 30, 5, 123_456_789).unwrap();/// assert_eq!(t.hour(), 21);/// assert_eq!(t.minute(), 30);/// assert_eq!(t.second(), 5);/// assert_eq!(t.millisecond(), 123);/// assert_eq!(t.microsecond(), 456);/// assert_eq!(t.nanosecond(), 789);/// This shows an example of an invalid time:/// assert!(Time::new(21, 30, 60, 0).is_err());midnight/// Returns the first moment of time in a day./// Specifically, this has the `hour`, `minute`, `second`, `millisecond`,/// `microsecond` and `nanosecond` fields all set to `0`./// let t = Time::midnight();/// assert_eq!(t.hour(), 0);/// assert_eq!(t.minute(), 0);/// assert_eq!(t.second(), 0);/// assert_eq!(t.millisecond(), 0);/// assert_eq!(t.microsecond(), 0);/// assert_eq!(t.nanosecond(), 0);/// Create a builder for constructing a `Time` from the fields of this/// See the methods on [`TimeWith`] for the different ways one can set the/// fields of a new `Time`./// Unlike [`Date`], a [`Time`] is valid for all possible valid values/// of its fields. That is, there is no way for two valid field values/// to combine into an invalid `Time`. So, for `Time`, this builder does/// have as much of a benefit versus an API design with methods like/// `Time::with_hour` and `Time::with_minute`. Nevertheless, this builder/// permits settings multiple fields at the same time and performing only/// one validity check. Moreover, this provides a consistent API with other/// date and time types in this crate./// let t1 = time(0, 0, 24, 0);/// let t2 = t1.with().hour(15).minute(30).millisecond(10).build()?;/// assert_eq!(t2, time(15, 30, 24, 10_000_000));/// Returns the "hour" component of this time./// let t = time(13, 35, 56, 123_456_789);/// assert_eq!(t.hour(), 13);/// Returns the "minute" component of this time./// assert_eq!(t.minute(), 35);/// Returns the "second" component of this time./// assert_eq!(t.second(), 56);/// Returns the "millisecond" component of this time./// Returns the "microsecond" component of this time./// Returns the "nanosecond" component of this time./// Returns the fractional nanosecond for this `Time` value./// If you want to set this value on `Time`, then use/// [`TimeWith::subsec_nanosecond`] via [`Time::with`]./// This shows the relationship between constructing a `Time` value/// let t = time(15, 21, 35, 0).with().millisecond(987).build()?;/// assert_eq!(t.subsec_nanosecond(), 987_000_000);/// This shows how the fractional nanosecond part of a `Time` value/// let time = zdt.datetime().time();/// assert_eq!(time.subsec_nanosecond(), 1_234);/// assert_eq!(time.subsec_nanosecond(), 999998766);/// assert_eq!(time.hour(), 23);/// assert_eq!(time.minute(), 59);/// assert_eq!(time.second(), 59);/// Given a [`Date`], this constructs a [`DateTime`] value with its time/// let d = date(2010, 3, 14);/// let t = time(2, 30, 0, 0);/// assert_eq!(DateTime::from_parts(d, t), t.to_datetime(d));/// A convenience function for constructing a [`DateTime`] from this time/// on the date given by its components./// This routine panics when [`Date::new`] with the given inputs would/// return an error. That is, when the given year-month-day does not/// correspond to a valid date. Namely, all of the following must be true:/// One can also flip the order by making use of [`Date::at`]:/// Add the given span to this time and wrap around on overflow./// `From` trait implementations for the [`TimeArithmetic`] type./// Given times `t1` and `t2`, and a span `s`, with `t2 = t1 + s`, it/// follows then that `t1 = t2 - s` for all values of `t1` and `s` that sum/// to `t2`./// In short, subtracting the given span from the sum returned by this/// function is guaranteed to result in precisely the original time./// This routine can be used via the `+` operator./// t + 1.hours().minutes(49).seconds(59),/// time(22, 0, 0, 0),/// # Example: add nanoseconds to a `Time`/// let t = time(22, 35, 1, 0);/// time(22, 35, 3, 500_000_000),/// t.wrapping_add(2_500_000_000i64.nanoseconds()),/// # Example: add span with multiple units/// t.wrapping_add(1.hours().minutes(49).seconds(59)),/// # Example: adding an empty span is a no-op/// use jiff::{civil::time, Span};/// assert_eq!(t, t.wrapping_add(Span::new()));/// # Example: addition wraps on overflow/// use jiff::{civil::time, SignedDuration, ToSpan};/// t.wrapping_add(1.nanoseconds()),/// time(0, 0, 0, 0),/// t.wrapping_add(SignedDuration::from_nanos(1)),/// t.wrapping_add(std::time::Duration::from_nanos(1)),/// Similarly, if there are any non-zero units greater than hours in the/// given span, then they also result in wrapping behavior (i.e., they are/// ignored):/// // doesn't matter what our time value is in this example/// let t = time(0, 0, 0, 0);/// assert_eq!(t, t.wrapping_add(1.days()));wrapping_add_spanwrapping_add_signed_durationwrapping_add_unsigned_duration/// This routine is identical to [`Time::wrapping_add`] with the duration/// t.wrapping_sub(1.nanoseconds()),/// time(23, 59, 59, 999_999_999),/// t.wrapping_sub(SignedDuration::from_nanos(1)),/// t.wrapping_sub(std::time::Duration::from_nanos(1)),/// t.wrapping_sub(SignedDuration::MIN),/// time(15, 30, 8, 999_999_999),/// t.wrapping_sub(SignedDuration::MAX),/// time(8, 29, 52, 1),/// t.wrapping_sub(std::time::Duration::MAX),/// time(16, 59, 44, 1),wrapping_sub_unsigned_duration/// Add the given span to this time and return an error if the result would/// otherwise overflow./// Given a time `t1` and a span `s`, and assuming `t2 = t1 + s` exists, it/// to a valid `t2`./// If the sum would overflow the minimum or maximum timestamp values, then/// an error is returned./// If the given span has any non-zero units greater than hours, then an/// t.checked_add(2_500_000_000i64.nanoseconds())?,/// t.checked_add(1.hours().minutes(49).seconds(59))?,/// assert_eq!(t, t.checked_add(Span::new())?);/// // okay/// let t = time(23, 59, 59, 999_999_998);/// t.with().nanosecond(999).build()?,/// t.checked_add(1.nanoseconds())?,/// // not okay/// assert!(t.checked_add(1.nanoseconds()).is_err());/// given span, then they also result in overflow (and thus an error):/// assert!(t.checked_add(1.days()).is_err());/// `Time`. As with adding a `Span`, any overflow that occurs results in/// use jiff::{civil::time, SignedDuration};/// let t = time(23, 0, 0, 0);/// let dur = SignedDuration::from_mins(30);/// assert_eq!(t.checked_add(dur)?, time(23, 30, 0, 0));/// assert_eq!(t.checked_add(-dur)?, time(22, 30, 0, 0));/// let dur = Duration::new(0, 1);/// assert_eq!(t.checked_add(dur)?, time(23, 0, 0, 1));/// This routine is identical to [`Time::checked_add`] with the duration/// This has the same error conditions as [`Time::checked_add`]./// let t = time(22, 0, 0, 0);/// t.checked_sub(1.hours().minutes(49).seconds(59))?,/// time(20, 10, 1, 0),/// t.checked_sub(SignedDuration::from_hours(1))?,/// time(21, 0, 0, 0),/// t.checked_sub(Duration::from_secs(60 * 60))?,/// This routine is identical to [`Time::checked_add`], except the/// [`Time::MIN`] or [`Time::MAX`] is returned./// use jiff::{civil::{Time, time}, SignedDuration, ToSpan};/// // no saturation/// t.saturating_add(1.nanoseconds()),/// // saturates/// assert_eq!(Time::MAX, t.saturating_add(1.nanoseconds()));/// assert_eq!(Time::MAX, t.saturating_add(SignedDuration::MAX));/// assert_eq!(Time::MIN, t.saturating_add(SignedDuration::MIN));/// assert_eq!(Time::MAX, t.saturating_add(std::time::Duration::MAX));/// given span, then they also result in overflow (and thus saturation):/// use jiff::{civil::{Time, time}, ToSpan};/// assert_eq!(Time::MAX, t.saturating_add(1.days()));/// This routine is identical to [`Time::saturating_add`] with the duration/// let t = time(0, 0, 0, 1);/// t.with().nanosecond(0).build()?,/// t.saturating_sub(1.nanoseconds()),/// assert_eq!(Time::MIN, t.saturating_sub(1.nanoseconds()));/// assert_eq!(Time::MIN, t.saturating_sub(SignedDuration::MAX));/// assert_eq!(Time::MAX, t.saturating_sub(SignedDuration::MIN));/// assert_eq!(Time::MIN, t.saturating_sub(std::time::Duration::MAX));overflowing_add/// Adds the given span to the this time value, and returns the resulting/// time with any overflowing amount in the span returned./// This isn't part of the public API because it seems a little odd, and/// I'm unsure of its use case. Overall this routine is a bit specialized/// and I'm not sure how generally useful it is. But it is used in crucial/// points in other parts of this crate./// If you want this public, please file an issue and discuss your use/// case: https://github.com/BurntSushi/jiff/issues/newoverflowing_add_duration/// Like `overflowing_add`, but with `SignedDuration`./// This is used for datetime arithmetic, when adding to the time/// component overflows into days (always 24 hours).overflowing_add_duration_general/// Returns a span representing the elapsed time from this time until/// the given `other` time./// When `other` is earlier than this time, the span returned will be/// also be balanced down to smaller units than the default. By default,/// the span returned is balanced such that the biggest possible unit is/// hours./// This operation is configured by providing a [`TimeDifference`]/// `Into`, once can pass a `Time` directly. One/// can also pass a `(Unit, Time)`, where `Unit` is treated as/// [`TimeDifference::largest`]./// As long as no rounding is requested, it is guaranteed that adding the/// span returned to the `other` time will always equal this time./// An error can occur if `TimeDifference` is misconfigured. For example,/// if the smallest unit provided is bigger than the largest unit, or if/// the largest unit is bigger than [`Unit::Hour`]./// It is guaranteed that if one provides a time with the default/// [`TimeDifference`] configuration, then this routine will never fail./// let t1 = time(22, 35, 1, 0);/// let t2 = time(22, 35, 3, 500_000_000);/// assert_eq!(t1.until(t2)?, 2.seconds().milliseconds(500).fieldwise());/// assert_eq!(t2.until(t1)?, -2.seconds().milliseconds(500).fieldwise());/// # Example: using smaller units/// This example shows how to contract the span returned to smaller units./// This makes use of a `From<(Unit, Time)> for TimeDifference`/// use jiff::{civil::time, Unit, ToSpan};/// let t1 = time(3, 24, 30, 3500);/// let t2 = time(15, 30, 0, 0);/// // The default limits spans to using "hours" as the biggest unit./// let span = t1.until(t2)?;/// assert_eq!(span.to_string(), "PT12H5M29.9999965S");/// // But we can ask for smaller units, like capping the biggest unit/// // to minutes instead of hours./// let span = t1.until((Unit::Minute, t2))?;/// assert_eq!(span.to_string(), "PT725M29.9999965S");/// This routine is identical to [`Time::until`], but the order of the/// This has the same error conditions as [`Time::until`]./// between any two possible times, it will never panic./// let earlier = time(1, 0, 0, 0);/// let later = time(22, 30, 0, 0);/// assert_eq!(later - earlier, 21.hours().minutes(30).fieldwise());/// time until the given `other` time./// When `other` occurs before this time, then the duration returned will/// Unlike [`Time::until`], this returns a duration corresponding to a/// 96-bit integer of nanoseconds between two times. In this case of/// computing durations between civil times where all days are assumed to/// be 24 hours long, the duration returned will always be less than 24/// possible when calling this routine. In contrast, [`Time::until`] can/// routine, [`Time::until`] never panics or returns an error in its/// # When should I use this versus [`Time::until`]?/// In short, use `Span` (and therefore `Time::until`) unless you have a/// assert_eq!(t1.duration_until(t2), SignedDuration::new(2, 500_000_000));/// // Flipping the time is fine, but you'll get a negative duration./// assert_eq!(t2.duration_until(t1), -SignedDuration::new(2, 500_000_000));/// # Example: difference with [`Time::until`]/// Since the difference between two civil times is always expressed in/// units of hours or smaller, and units of hours or smaller are always/// uniform, there is no "expressive" difference between this routine and/// `Time::until`. The only difference is that this routine returns a/// `SignedDuration` and `Time::until` returns a [`Span`]. Moreover, since/// the difference is always less than 24 hours, the return values can/// always be infallibly and losslessly converted between each other:/// use jiff::{civil::time, SignedDuration, Span};/// let dur = t1.duration_until(t2);/// // Guaranteed to never fail because the duration/// // between two civil times never exceeds the limits/// // of a `Span`./// let span = Span::try_from(dur).unwrap();/// assert_eq!(span, Span::new().seconds(2).milliseconds(500).fieldwise());/// // Guaranteed to succeed and always return the original/// // duration because the units are always hours or smaller,/// // and thus uniform. This means a relative datetime is/// // never required to do this conversion./// let dur = SignedDuration::try_from(span).unwrap();/// assert_eq!(dur, SignedDuration::new(2, 500_000_000));/// This conversion guarantee also applies to [`Time::until`] since it/// always returns a balanced span. That is, it never returns spans like/// `1 second 1000 milliseconds`. (Those cannot be losslessly converted to/// a `SignedDuration` since a `SignedDuration` is only represented as a/// single 96-bit integer of nanoseconds.)/// If you're looking to find the duration between two times as a/// let dur = Duration::try_from(t1.duration_until(t2))?;;/// assert_eq!(dur, Duration::new(2, 500_000_000));/// assert!(Duration::try_from(t2.duration_until(t1)).is_err());/// This routine is identical to [`Time::duration_until`], but the order of/// SignedDuration::from_secs((21 * 60 * 60) + (30 * 60)),/// Rounds this time according to the [`TimeRound`] configuration given./// The principal option is [`TimeRound::smallest`], which allows one/// to configure the smallest units in the returned time. Rounding/// be incremented can be configured via [`TimeRound::increment`]./// [`TimeRound::mode`]./// implements `Into`. Some notable implementations are:/// * `From for Round`, which will automatically create a/// `TimeRound::new().smallest(unit)` from the unit provided./// * `From<(Unit, i64)> for Round`, which will automatically create a/// `TimeRound::new().smallest(unit).increment(number)` from the unit/// and increment provided./// [`TimeRound`] is bigger than hours./// The rounding increment must divide evenly into the next highest unit/// after the smallest unit configured (and must not be equivalent to it)./// For example, if the smallest unit is [`Unit::Nanosecond`], then *some*/// of the valid values for the rounding increment are `1`, `2`, `4`, `5`,/// `100` and `500`. Namely, any integer that divides evenly into `1,000`/// nanoseconds since there are `1,000` nanoseconds in the next highest/// unit (microseconds)./// This can never fail because of overflow for any input. The only/// possible errors are "configuration" errors./// nearest second. This also demonstrates calling this method with the/// smallest unit directly, instead of constructing a `TimeRound` manually./// use jiff::{civil::time, Unit};/// let t = time(15, 45, 10, 123_456_789);/// t.round(Unit::Second)?,/// time(15, 45, 10, 0),/// let t = time(15, 45, 10, 500_000_001);/// time(15, 45, 11, 0),/// use jiff::{civil::{TimeRound, time}, RoundMode, Unit};/// let t = time(15, 45, 10, 999_999_999);/// // The default will round up to the next second for any fraction/// // greater than or equal to 0.5. But truncation will always round/// // toward zero./// t.round(/// TimeRound::new().smallest(Unit::Second).mode(RoundMode::Trunc),/// let t = time(15, 27, 29, 999_999_999);/// assert_eq!(t.round((Unit::Minute, 5))?, time(15, 25, 0, 0));/// let t = time(15, 27, 30, 0);/// assert_eq!(t.round((Unit::Minute, 5))?, time(15, 30, 0, 0));/// # Example: rounding wraps around on overflow/// overflow, and as a result, have the time wrap around./// use jiff::{civil::Time, Unit};/// let t = Time::MAX;/// assert_eq!(t.round(Unit::Hour)?, Time::MIN);/// Return an iterator of periodic times determined by the given span./// `Time` value./// # Example: visiting every third hour/// This shows how to visit each third hour of a 24 hour time interval:/// let start = Time::MIN;/// let mut every_third_hour = vec![];/// for t in start.series(3.hours()) {/// every_third_hour.push(t);/// assert_eq!(every_third_hour, vec![/// time(3, 0, 0, 0),/// time(6, 0, 0, 0),/// time(9, 0, 0, 0),/// time(12, 0, 0, 0),/// time(18, 0, 0, 0),/// Or go backwards every 6.5 hours:/// let start = time(23, 0, 0, 0);/// let times: Vec