Struct Time

struct Time { ... }

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.

Parsing and printing

The Time type provides convenient trait implementations of std::str::FromStr and [std::fmt::Display]:

use jiff::civil::Time;

let t: Time = "15:22:45".parse()?;
assert_eq!(t.to_string(), "15:22:45");

# Ok::<(), Box<dyn std::error::Error>>(())

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):

use jiff::civil::Time;

let t: Time = "2024-06-19T15:22:45-04[America/New_York]".parse()?;
assert_eq!(t.to_string(), "15:22:45");

# Ok::<(), Box<dyn std::error::Error>>(())

For more information on the specific format supported, see the fmt::temporal module documentation.

Default value

For convenience, this type implements the Default trait. Its default value is midnight. i.e., 00:00:00.000000000.

Leap seconds

Jiff does not support leap seconds. Jiff behaves as if they don't exist. The only exception is that if one parses a time with a second component of 60, then it is automatically constrained to 59:

use jiff::civil::{Time, time};

let t: Time = "23:59:60".parse()?;
assert_eq!(t, time(23, 59, 59, 0));

# Ok::<(), Box<dyn std::error::Error>>(())

Comparisons

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:

use jiff::civil::time;

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.

Arithmetic

This type provides routines for adding and subtracting spans of time, as well as computing the span of time between two Time values.

For adding or subtracting spans of time, one can use any of the following routines:

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:

use jiff::{civil::time, ToSpan};

let time1 = time(22, 0, 0, 0);
let time2 = time(20, 10, 1, 0);
assert_eq!(
    time1 - time2,
    1.hours().minutes(49).seconds(59).fieldwise(),
);

The until and since APIs are polymorphic and allow re-balancing and 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);
assert_eq!(
    time1.since((Unit::Minute, time2))?,
    990.minutes().fieldwise(),
);

# Ok::<(), Box<dyn std::error::Error>>(())

Or even round the span returned:

use jiff::{civil::{TimeDifference, time}, RoundMode, ToSpan, Unit};

let time1 = time(23, 30, 0, 0);
let time2 = time(23, 35, 59, 0);
assert_eq!(
    time1.until(
        TimeDifference::new(time2).smallest(Unit::Minute),
    )?,
    5.minutes().fieldwise(),
);
// `TimeDifference` uses truncation as a rounding mode by default,
// but you can set the rounding mode to break ties away from zero:
assert_eq!(
    time1.until(
        TimeDifference::new(time2)
            .smallest(Unit::Minute)
            .mode(RoundMode::HalfExpand),
    )?,
    // Rounds up to 6 minutes.
    6.minutes().fieldwise(),
);

# Ok::<(), Box<dyn std::error::Error>>(())

Rounding

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);
assert_eq!(
    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`
// trait implementation:
assert_eq!(t.round((Unit::Hour, 3))?, time(15, 0, 0, 0));

# Ok::<(), Box<dyn std::error::Error>>(())

See Time::round for more details.

Implementations

impl Time

fn strptime<impl AsRef<[u8]>: AsRef<[u8]>, impl AsRef<[u8]>: AsRef<[u8]>>(format: impl AsRef<[u8]>, input: impl AsRef<[u8]>) -> Result<Time, Error>

Parses a civil time in input matching the given format.

The format string uses a "printf"-style API where conversion specifiers can be used as place holders to match components of a datetime. For details on the specifiers supported, see the fmt::strtime module documentation.

Errors

This returns an error when parsing failed. This might happen because the format string itself was invalid, or because the input didn't match the format string.

This also returns an error if there wasn't sufficient information to construct a civil time. For example, if an offset wasn't parsed.

Example

This example shows how to parse a civil time:

use jiff::civil::Time;

// Parse with a 12-hour clock.
let time = Time::strptime("%I:%M%P", "4:30pm")?;
assert_eq!(time.to_string(), "16:30:00");

# Ok::<(), Box<dyn std::error::Error>>(())
fn strftime<'f, F: 'f + ?Sized + AsRef<[u8]>>(self: &Self, format: &'f F) -> Display<'f>

Formats this civil time according to the given format.

The format string uses a "printf"-style API where conversion specifiers can be used as place holders to format components of a datetime. For details on the specifiers supported, see the fmt::strtime module documentation.

Errors and panics

While this routine itself does not error or panic, using the value returned may result in a panic if formatting fails. See the documentation on fmt::strtime::Display for more information.

To format in a way that surfaces errors without panicking, use either fmt::strtime::format or fmt::strtime::BrokenDownTime::format.

Example

This example shows how to format a civil time in a 12 hour clock with no padding for the hour:

use jiff::civil::time;

let t = time(16, 30, 59, 0);
let string = t.strftime("%-I:%M%P").to_string();
assert_eq!(string, "4:30pm");

Note that one can round a Time before formatting. For example, to round to the nearest minute:

use jiff::{civil::time, Unit};

let t = time(16, 30, 59, 0);
let string = t.round(Unit::Minute)?.strftime("%-I:%M%P").to_string();
assert_eq!(string, "4:31pm");

# Ok::<(), Box<dyn std::error::Error>>(())

impl Time

fn new(hour: i8, minute: i8, second: i8, subsec_nanosecond: i32) -> Result<Time, Error>

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.

Errors

This returns an error unless all of the following conditions are true:

  • 0 <= hour <= 23
  • 0 <= minute <= 59
  • 0 <= second <= 59
  • 0 <= subsec_nanosecond <= 999,999,999

Example

This shows an example of a valid time:

use jiff::civil::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:

use jiff::civil::Time;

assert!(Time::new(21, 30, 60, 0).is_err());
const fn constant(hour: i8, minute: i8, second: i8, subsec_nanosecond: i32) -> Time

Creates a new Time value in a const context.

Panics

This panics if the given values do not correspond to a valid Time. All of the following conditions must be true:

  • 0 <= hour <= 23
  • 0 <= minute <= 59
  • 0 <= second <= 59
  • 0 <= subsec_nanosecond <= 999,999,999

Similarly, when used in a const context, invalid parameters will prevent your Rust program from compiling.

Example

This shows an example of a valid time in a const context:

use jiff::civil::Time;

const BEDTIME: Time = Time::constant(21, 30, 5, 123_456_789);
assert_eq!(BEDTIME.hour(), 21);
assert_eq!(BEDTIME.minute(), 30);
assert_eq!(BEDTIME.second(), 5);
assert_eq!(BEDTIME.millisecond(), 123);
assert_eq!(BEDTIME.microsecond(), 456);
assert_eq!(BEDTIME.nanosecond(), 789);
assert_eq!(BEDTIME.subsec_nanosecond(), 123_456_789);
const fn midnight() -> Time

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.

Example

use jiff::civil::Time;

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);
fn with(self: Self) -> TimeWith

Create a builder for constructing a Time from the fields of this time.

See the methods on TimeWith for the different ways one can set the fields of a new Time.

Example

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.

use jiff::civil::time;

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));

# Ok::<(), Box<dyn std::error::Error>>(())
fn hour(self: Self) -> i8

Returns the "hour" component of this time.

The value returned is guaranteed to be in the range 0..=23.

Example

use jiff::civil::time;

let t = time(13, 35, 56, 123_456_789);
assert_eq!(t.hour(), 13);
fn minute(self: Self) -> i8

Returns the "minute" component of this time.

The value returned is guaranteed to be in the range 0..=59.

Example

use jiff::civil::time;

let t = time(13, 35, 56, 123_456_789);
assert_eq!(t.minute(), 35);
fn second(self: Self) -> i8

Returns the "second" component of this time.

The value returned is guaranteed to be in the range 0..=59.

Example

use jiff::civil::time;

let t = time(13, 35, 56, 123_456_789);
assert_eq!(t.second(), 56);
fn millisecond(self: Self) -> i16

Returns the "millisecond" component of this time.

The value returned is guaranteed to be in the range 0..=999.

Example

use jiff::civil::time;

let t = time(13, 35, 56, 123_456_789);
assert_eq!(t.millisecond(), 123);
fn microsecond(self: Self) -> i16

Returns the "microsecond" component of this time.

The value returned is guaranteed to be in the range 0..=999.

Example

use jiff::civil::time;

let t = time(13, 35, 56, 123_456_789);
assert_eq!(t.microsecond(), 456);
fn nanosecond(self: Self) -> i16

Returns the "nanosecond" component of this time.

The value returned is guaranteed to be in the range 0..=999.

Example

use jiff::civil::time;

let t = time(13, 35, 56, 123_456_789);
assert_eq!(t.nanosecond(), 789);
fn subsec_nanosecond(self: Self) -> i32

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.

The value returned is guaranteed to be in the range 0..=999_999_999.

Example

This shows the relationship between constructing a Time value with routines like with().millisecond() and accessing the entire fractional part as a nanosecond:

use jiff::civil::time;

let t = time(15, 21, 35, 0).with().millisecond(987).build()?;
assert_eq!(t.subsec_nanosecond(), 987_000_000);

# Ok::<(), Box<dyn std::error::Error>>(())

Example: nanoseconds from a timestamp

This shows how the fractional nanosecond part of a Time value manifests from a specific timestamp.

use jiff::{civil, Timestamp};

// 1,234 nanoseconds after the Unix epoch.
let zdt = Timestamp::new(0, 1_234)?.in_tz("UTC")?;
let time = zdt.datetime().time();
assert_eq!(time.subsec_nanosecond(), 1_234);

// 1,234 nanoseconds before the Unix epoch.
let zdt = Timestamp::new(0, -1_234)?.in_tz("UTC")?;
let time = zdt.datetime().time();
// The nanosecond is equal to `1_000_000_000 - 1_234`.
assert_eq!(time.subsec_nanosecond(), 999998766);
// Looking at the other components of the time value might help.
assert_eq!(time.hour(), 23);
assert_eq!(time.minute(), 59);
assert_eq!(time.second(), 59);

# Ok::<(), Box<dyn std::error::Error>>(())
const fn to_datetime(self: Self, date: Date) -> DateTime

Given a Date, this constructs a DateTime value with its time component equal to this time.

This is a convenience function for DateTime::from_parts.

Example

use jiff::civil::{DateTime, date, 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));
const fn on(self: Self, year: i16, month: i8, day: i8) -> DateTime

A convenience function for constructing a DateTime from this time on the date given by its components.

Example

use jiff::civil::time;

assert_eq!(
    time(2, 30, 0, 0).on(2010, 3, 14).to_string(),
    "2010-03-14T02:30:00",
);

One can also flip the order by making use of [Date::at]:

use jiff::civil::date;

assert_eq!(
    date(2010, 3, 14).at(2, 30, 0, 0).to_string(),
    "2010-03-14T02:30:00",
);
fn wrapping_add<A: Into<TimeArithmetic>>(self: Self, duration: A) -> Time

Add the given span to this time and wrap around on overflow.

This operation accepts three different duration types: Span, SignedDuration or std::time::Duration. This is achieved via From trait implementations for the TimeArithmetic type.

Properties

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.

Example: available via addition operator

This routine can be used via the + operator.

use jiff::{civil::time, ToSpan};

let t = time(20, 10, 1, 0);
assert_eq!(
    t + 1.hours().minutes(49).seconds(59),
    time(22, 0, 0, 0),
);

Example: add nanoseconds to a Time

use jiff::{civil::time, ToSpan};

let t = time(22, 35, 1, 0);
assert_eq!(
    time(22, 35, 3, 500_000_000),
    t.wrapping_add(2_500_000_000i64.nanoseconds()),
);

Example: add span with multiple units

use jiff::{civil::time, ToSpan};

let t = time(20, 10, 1, 0);
assert_eq!(
    time(22, 0, 0, 0),
    t.wrapping_add(1.hours().minutes(49).seconds(59)),
);

Example: adding an empty span is a no-op

use jiff::{civil::time, Span};

let t = time(20, 10, 1, 0);
assert_eq!(t, t.wrapping_add(Span::new()));

Example: addition wraps on overflow

use jiff::{civil::time, SignedDuration, ToSpan};

let t = time(23, 59, 59, 999_999_999);
assert_eq!(
    t.wrapping_add(1.nanoseconds()),
    time(0, 0, 0, 0),
);
assert_eq!(
    t.wrapping_add(SignedDuration::from_nanos(1)),
    time(0, 0, 0, 0),
);
assert_eq!(
    t.wrapping_add(std::time::Duration::from_nanos(1)),
    time(0, 0, 0, 0),
);

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):

use jiff::{civil::time, ToSpan};

// 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()));
fn wrapping_sub<A: Into<TimeArithmetic>>(self: Self, duration: A) -> Time

This routine is identical to Time::wrapping_add with the duration negated.

Example

use jiff::{civil::time, SignedDuration, ToSpan};

let t = time(0, 0, 0, 0);
assert_eq!(
    t.wrapping_sub(1.nanoseconds()),
    time(23, 59, 59, 999_999_999),
);
assert_eq!(
    t.wrapping_sub(SignedDuration::from_nanos(1)),
    time(23, 59, 59, 999_999_999),
);
assert_eq!(
    t.wrapping_sub(std::time::Duration::from_nanos(1)),
    time(23, 59, 59, 999_999_999),
);

assert_eq!(
    t.wrapping_sub(SignedDuration::MIN),
    time(15, 30, 8, 999_999_999),
);
assert_eq!(
    t.wrapping_sub(SignedDuration::MAX),
    time(8, 29, 52, 1),
);
assert_eq!(
    t.wrapping_sub(std::time::Duration::MAX),
    time(16, 59, 44, 1),
);
fn checked_add<A: Into<TimeArithmetic>>(self: Self, duration: A) -> Result<Time, Error>

Add the given span to this time and return an error if the result would otherwise overflow.

This operation accepts three different duration types: Span, SignedDuration or std::time::Duration. This is achieved via From trait implementations for the TimeArithmetic type.

Properties

Given a time t1 and a span s, and assuming t2 = t1 + s exists, it follows then that t1 = t2 - s for all values of t1 and s that sum to a valid t2.

In short, subtracting the given span from the sum returned by this function is guaranteed to result in precisely the original time.

Errors

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 error is returned.

Example: add nanoseconds to a Time

use jiff::{civil::time, ToSpan};

let t = time(22, 35, 1, 0);
assert_eq!(
    time(22, 35, 3, 500_000_000),
    t.checked_add(2_500_000_000i64.nanoseconds())?,
);
# Ok::<(), Box<dyn std::error::Error>>(())

Example: add span with multiple units

use jiff::{civil::time, ToSpan};

let t = time(20, 10, 1, 0);
assert_eq!(
    time(22, 0, 0, 0),
    t.checked_add(1.hours().minutes(49).seconds(59))?,
);
# Ok::<(), Box<dyn std::error::Error>>(())

Example: adding an empty span is a no-op

use jiff::{civil::time, Span};

let t = time(20, 10, 1, 0);
assert_eq!(t, t.checked_add(Span::new())?);

# Ok::<(), Box<dyn std::error::Error>>(())

Example: error on overflow

use jiff::{civil::time, ToSpan};

// okay
let t = time(23, 59, 59, 999_999_998);
assert_eq!(
    t.with().nanosecond(999).build()?,
    t.checked_add(1.nanoseconds())?,
);

// not okay
let t = time(23, 59, 59, 999_999_999);
assert!(t.checked_add(1.nanoseconds()).is_err());

# Ok::<(), Box<dyn std::error::Error>>(())

Similarly, if there are any non-zero units greater than hours in the given span, then they also result in overflow (and thus an error):

use jiff::{civil::time, ToSpan};

// doesn't matter what our time value is in this example
let t = time(0, 0, 0, 0);
assert!(t.checked_add(1.days()).is_err());

Example: adding absolute durations

This shows how to add signed and unsigned absolute durations to a Time. As with adding a Span, any overflow that occurs results in an error.

use std::time::Duration;

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));

# Ok::<(), Box<dyn std::error::Error>>(())
fn checked_sub<A: Into<TimeArithmetic>>(self: Self, duration: A) -> Result<Time, Error>

This routine is identical to Time::checked_add with the duration negated.

Errors

This has the same error conditions as Time::checked_add.

Example

use std::time::Duration;

use jiff::{civil::time, SignedDuration, ToSpan};

let t = time(22, 0, 0, 0);
assert_eq!(
    t.checked_sub(1.hours().minutes(49).seconds(59))?,
    time(20, 10, 1, 0),
);
assert_eq!(
    t.checked_sub(SignedDuration::from_hours(1))?,
    time(21, 0, 0, 0),
);
assert_eq!(
    t.checked_sub(Duration::from_secs(60 * 60))?,
    time(21, 0, 0, 0),
);
# Ok::<(), Box<dyn std::error::Error>>(())
fn saturating_add<A: Into<TimeArithmetic>>(self: Self, duration: A) -> Time

This routine is identical to Time::checked_add, except the result saturates on overflow. That is, instead of overflow, either Time::MIN or Time::MAX is returned.

Example

use jiff::{civil::{Time, time}, SignedDuration, ToSpan};

// no saturation
let t = time(23, 59, 59, 999_999_998);
assert_eq!(
    t.with().nanosecond(999).build()?,
    t.saturating_add(1.nanoseconds()),
);

// saturates
let t = time(23, 59, 59, 999_999_999);
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));

# Ok::<(), Box<dyn std::error::Error>>(())

Similarly, if there are any non-zero units greater than hours in the given span, then they also result in overflow (and thus saturation):

use jiff::{civil::{Time, time}, ToSpan};

// doesn't matter what our time value is in this example
let t = time(0, 0, 0, 0);
assert_eq!(Time::MAX, t.saturating_add(1.days()));
fn saturating_sub<A: Into<TimeArithmetic>>(self: Self, duration: A) -> Time

This routine is identical to Time::saturating_add with the duration negated.

Example

use jiff::{civil::{Time, time}, SignedDuration, ToSpan};

// no saturation
let t = time(0, 0, 0, 1);
assert_eq!(
    t.with().nanosecond(0).build()?,
    t.saturating_sub(1.nanoseconds()),
);

// saturates
let t = time(0, 0, 0, 0);
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));

# Ok::<(), Box<dyn std::error::Error>>(())
fn until<A: Into<TimeDifference>>(self: Self, other: A) -> Result<Span, Error>

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 negative.

Depending on the input provided, the span returned is rounded. It may 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 value. Since this routine accepts anything that implements Into<TimeDifference>, once can pass a Time directly. One can also pass a (Unit, Time), where Unit is treated as TimeDifference::largest.

Properties

As long as no rounding is requested, it is guaranteed that adding the span returned to the other time will always equal this time.

Errors

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.

Examples

use jiff::{civil::time, ToSpan};

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());
// Flipping the dates is fine, but you'll get a negative span.
assert_eq!(t2.until(t1)?, -2.seconds().milliseconds(500).fieldwise());

# Ok::<(), Box<dyn std::error::Error>>(())

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 trait implementation.

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");

# Ok::<(), Box<dyn std::error::Error>>(())
fn since<A: Into<TimeDifference>>(self: Self, other: A) -> Result<Span, Error>

This routine is identical to Time::until, but the order of the parameters is flipped.

Errors

This has the same error conditions as Time::until.

Example

This routine can be used via the - operator. Since the default configuration is used and because a Span can represent the difference between any two possible times, it will never panic.

use jiff::{civil::time, ToSpan};

let earlier = time(1, 0, 0, 0);
let later = time(22, 30, 0, 0);
assert_eq!(later - earlier, 21.hours().minutes(30).fieldwise());
fn duration_until(self: Self, other: Time) -> SignedDuration

Returns an absolute duration representing the elapsed time from this time until the given other time.

When other occurs before this time, then the duration returned will be negative.

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 hours.

Fallibility

This routine never panics or returns an error. Since there are no configuration options that can be incorrectly provided, no error is possible when calling this routine. In contrast, Time::until can return an error in some cases due to misconfiguration. But like this routine, Time::until never panics or returns an error in its default configuration.

When should I use this versus Time::until?

See the type documentation for SignedDuration for the section on when one should use Span and when one should use SignedDuration. In short, use Span (and therefore Time::until) unless you have a specific reason to do otherwise.

Example

use jiff::{civil::time, SignedDuration};

let t1 = time(22, 35, 1, 0);
let t2 = time(22, 35, 3, 500_000_000);
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 t1 = time(22, 35, 1, 0);
let t2 = time(22, 35, 3, 500_000_000);
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.)

Example: getting an unsigned duration

If you're looking to find the duration between two times as a std::time::Duration, you'll need to use this method to get a SignedDuration and then convert it to a std::time::Duration:

use std::time::Duration;

use jiff::{civil::time, SignedDuration, Span};

let t1 = time(22, 35, 1, 0);
let t2 = time(22, 35, 3, 500_000_000);
let dur = Duration::try_from(t1.duration_until(t2))?;;
assert_eq!(dur, Duration::new(2, 500_000_000));

// Note that unsigned durations cannot represent all
// possible differences! If the duration would be negative,
// then the conversion fails:
assert!(Duration::try_from(t2.duration_until(t1)).is_err());

# Ok::<(), Box<dyn std::error::Error>>(())
fn duration_since(self: Self, other: Time) -> SignedDuration

This routine is identical to Time::duration_until, but the order of the parameters is flipped.

Example

use jiff::{civil::time, SignedDuration};

let earlier = time(1, 0, 0, 0);
let later = time(22, 30, 0, 0);
assert_eq!(
    later.duration_since(earlier),
    SignedDuration::from_secs((21 * 60 * 60) + (30 * 60)),
);
fn round<R: Into<TimeRound>>(self: Self, options: R) -> Result<Time, Error>

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 is what determines whether that unit should keep its current value or whether it should be incremented. Moreover, the amount it should be incremented can be configured via TimeRound::increment. Finally, the rounding strategy itself can be configured via TimeRound::mode.

Note that this routine is generic and accepts anything that implements Into<TimeRound>. Some notable implementations are:

  • From<Unit> 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.

Errors

This returns an error if the smallest unit configured on the given 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.

Example

This is a basic example that demonstrates rounding a datetime to the 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);
assert_eq!(
    t.round(Unit::Second)?,
    time(15, 45, 10, 0),
);
let t = time(15, 45, 10, 500_000_001);
assert_eq!(
    t.round(Unit::Second)?,
    time(15, 45, 11, 0),
);

# Ok::<(), Box<dyn std::error::Error>>(())

Example: changing the rounding mode

The default rounding mode is RoundMode::HalfExpand, which breaks ties by rounding away from zero. But other modes like RoundMode::Trunc can be used too:

use jiff::{civil::{TimeRound, time}, RoundMode, Unit};

let t = time(15, 45, 10, 999_999_999);
assert_eq!(
    t.round(Unit::Second)?,
    time(15, 45, 11, 0),
);
// 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.
assert_eq!(
    t.round(
        TimeRound::new().smallest(Unit::Second).mode(RoundMode::Trunc),
    )?,
    time(15, 45, 10, 0),
);

# Ok::<(), Box<dyn std::error::Error>>(())

Example: rounding to the nearest 5 minute increment

use jiff::{civil::time, Unit};

// rounds down
let t = time(15, 27, 29, 999_999_999);
assert_eq!(t.round((Unit::Minute, 5))?, time(15, 25, 0, 0));
// rounds up
let t = time(15, 27, 30, 0);
assert_eq!(t.round((Unit::Minute, 5))?, time(15, 30, 0, 0));

# Ok::<(), Box<dyn std::error::Error>>(())

Example: rounding wraps around on overflow

This example demonstrates that it's possible for this operation to 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);

# Ok::<(), Box<dyn std::error::Error>>(())
fn series(self: Self, period: Span) -> TimeSeries

Return an iterator of periodic times determined by the given span.

The given span may be negative, in which case, the iterator will move backwards through time. The iterator won't stop until either the span itself overflows, or it would otherwise exceed the minimum or maximum Time value.

Example: visiting every third hour

This shows how to visit each third hour of a 24 hour time interval:

use jiff::{civil::{Time, time}, ToSpan};

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(0, 0, 0, 0),
    time(3, 0, 0, 0),
    time(6, 0, 0, 0),
    time(9, 0, 0, 0),
    time(12, 0, 0, 0),
    time(15, 0, 0, 0),
    time(18, 0, 0, 0),
    time(21, 0, 0, 0),
]);

Or go backwards every 6.5 hours:

use jiff::{civil::{Time, time}, ToSpan};

let start = time(23, 0, 0, 0);
let times: Vec<Time> = start.series(-6.hours().minutes(30)).collect();
assert_eq!(times, vec![
    time(23, 0, 0, 0),
    time(16, 30, 0, 0),
    time(10, 0, 0, 0),
    time(3, 30, 0, 0),
]);

impl Add for Time

fn add(self: Self, rhs: SignedDuration) -> Time

impl Add for Time

fn add(self: Self, rhs: UnsignedDuration) -> Time

impl Add for Time

fn add(self: Self, rhs: Span) -> Time

impl AddAssign for Time

fn add_assign(self: &mut Self, rhs: SignedDuration)

impl AddAssign for Time

fn add_assign(self: &mut Self, rhs: UnsignedDuration)

impl AddAssign for Time

fn add_assign(self: &mut Self, rhs: Span)

impl Clone for Time

fn clone(self: &Self) -> Time

impl Copy for Time

impl Debug for Time

fn fmt(self: &Self, f: &mut Formatter<'_>) -> Result

impl Default for Time

fn default() -> Time

impl Display for Time

fn fmt(self: &Self, f: &mut Formatter<'_>) -> Result

impl Eq for Time

impl Freeze for Time

impl From for Time

fn from(dt: DateTime) -> Time

impl From for Time

fn from(zdt: Zoned) -> Time

impl FromStr for Time

fn from_str(string: &str) -> Result<Time, Error>

impl Hash for Time

fn hash<__H: $crate::hash::Hasher>(self: &Self, state: &mut __H)

impl Ord for Time

fn cmp(self: &Self, other: &Time) -> Ordering

impl PartialEq for Time

fn eq(self: &Self, other: &Time) -> bool

impl PartialOrd for Time

fn partial_cmp(self: &Self, other: &Time) -> Option<Ordering>

impl RefUnwindSafe for Time

impl Send for Time

impl Serialize for Time

fn serialize<S: serde::Serializer>(self: &Self, serializer: S) -> Result<<S as >::Ok, <S as >::Error>

impl StructuralPartialEq for Time

impl Sub for Time

fn sub(self: Self, rhs: SignedDuration) -> Time

impl Sub for Time

fn sub(self: Self, rhs: UnsignedDuration) -> Time

impl Sub for Time

fn sub(self: Self, rhs: Span) -> Time

impl Sub for Time

fn sub(self: Self, rhs: Time) -> Span

impl SubAssign for Time

fn sub_assign(self: &mut Self, rhs: SignedDuration)

impl SubAssign for Time

fn sub_assign(self: &mut Self, rhs: UnsignedDuration)

impl SubAssign for Time

fn sub_assign(self: &mut Self, rhs: Span)

impl Sync for Time

impl Unpin for Time

impl UnsafeUnpin for Time

impl UnwindSafe for Time

impl<'a> From for Time

fn from(zdt: &'a Zoned) -> Time

impl<'de> Deserialize for Time

fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Time, <D as >::Error>

impl<T> Any for Time

fn type_id(self: &Self) -> TypeId

impl<T> Borrow for Time

fn borrow(self: &Self) -> &T

impl<T> BorrowMut for Time

fn borrow_mut(self: &mut Self) -> &mut T

impl<T> CloneToUninit for Time

unsafe fn clone_to_uninit(self: &Self, dest: *mut u8)

impl<T> DeserializeOwned for Time

impl<T> From for Time

fn from(t: T) -> T

Returns the argument unchanged.

impl<T> ToOwned for Time

fn to_owned(self: &Self) -> T
fn clone_into(self: &Self, target: &mut T)

impl<T> ToString for Time

fn to_string(self: &Self) -> String

impl<T, U> Into for Time

fn into(self: Self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

impl<T, U> TryFrom for Time

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

impl<T, U> TryInto for Time

fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>