rustmax::jiff::civil

Struct Time

Source
pub struct Time { /* private fields */ }
Expand description

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

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

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

§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(),
);

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

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

See Time::round for more details.

Implementations§

Source§

impl Time

Source

pub const MIN: Time = _

The minimum representable time value.

This corresponds to 00:00:00.000000000.

Source

pub const MAX: Time = _

The maximum representable time value.

This corresponds to 23:59:59.999999999.

Source

pub 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());
Source

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

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

pub fn with(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));
Source

pub fn hour(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);
Source

pub fn minute(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);
Source

pub fn second(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);
Source

pub fn millisecond(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);
Source

pub fn microsecond(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);
Source

pub fn nanosecond(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);
Source

pub fn subsec_nanosecond(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);
§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);
Source

pub const fn to_datetime(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));
Source

pub const fn on(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",
);
Source

pub fn wrapping_add<A>(self, duration: A) -> Time
where A: Into<TimeArithmetic>,

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

pub fn wrapping_sub<A>(self, duration: A) -> Time
where A: Into<TimeArithmetic>,

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

pub fn checked_add<A>(self, duration: A) -> Result<Time, Error>
where A: Into<TimeArithmetic>,

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())?,
);
§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))?,
);
§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())?);
§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());

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

pub fn checked_sub<A>(self, duration: A) -> Result<Time, Error>
where A: Into<TimeArithmetic>,

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

pub fn saturating_add<A>(self, duration: A) -> Time
where A: Into<TimeArithmetic>,

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

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

pub fn saturating_sub<A>(self, duration: A) -> Time
where A: Into<TimeArithmetic>,

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

pub fn until<A>(self, other: A) -> Result<Span, Error>
where A: Into<TimeDifference>,

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());
§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");
Source

pub fn since<A>(self, other: A) -> Result<Span, Error>
where A: Into<TimeDifference>,

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

pub fn duration_until(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());
Source

pub fn duration_since(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)),
);
Source

pub fn round<R>(self, options: R) -> Result<Time, Error>
where R: Into<TimeRound>,

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),
);
§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),
);
§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));
§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);
Source

pub fn series(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),
]);
Source§

impl Time

Parsing and formatting using a “printf”-style API.

Source

pub fn strptime( 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");
Source

pub fn strftime<'f, F>(&self, format: &'f F) -> Display<'f>
where F: 'f + AsRef<[u8]> + ?Sized,

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

impl Time

This impl block contains no items.

Crate internal APIs.

Many of these are mirrors of the public API, but on ranged types. These are often much more convenient to use in composition with other parts of the crate that also use ranged integer types. And this often permits the routines to be infallible and (possibly) zero-cost.

Trait Implementations§

Source§

impl Add<Duration> for Time

Adds an unsigned duration of time. This uses wrapping arithmetic.

For checked arithmetic, see Time::checked_add.

Source§

type Output = Time

The resulting type after applying the + operator.
Source§

fn add(self, rhs: Duration) -> Time

Performs the + operation. Read more
Source§

impl Add<SignedDuration> for Time

Adds a signed duration of time. This uses wrapping arithmetic.

For checked arithmetic, see Time::checked_add.

Source§

type Output = Time

The resulting type after applying the + operator.
Source§

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

Performs the + operation. Read more
Source§

impl Add<Span> for Time

Adds a span of time. This uses wrapping arithmetic.

For checked arithmetic, see Time::checked_add.

Source§

type Output = Time

The resulting type after applying the + operator.
Source§

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

Performs the + operation. Read more
Source§

impl AddAssign<Duration> for Time

Adds an unsigned duration of time in place. This uses wrapping arithmetic.

For checked arithmetic, see Time::checked_add.

Source§

fn add_assign(&mut self, rhs: Duration)

Performs the += operation. Read more
Source§

impl AddAssign<SignedDuration> for Time

Adds a signed duration of time in place. This uses wrapping arithmetic.

For checked arithmetic, see Time::checked_add.

Source§

fn add_assign(&mut self, rhs: SignedDuration)

Performs the += operation. Read more
Source§

impl AddAssign<Span> for Time

Adds a span of time in place. This uses wrapping arithmetic.

For checked arithmetic, see Time::checked_add.

Source§

fn add_assign(&mut self, rhs: Span)

Performs the += operation. Read more
Source§

impl Clone for Time

Source§

fn clone(&self) -> Time

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Time

Converts a Time into a human readable time string.

(This Debug representation currently emits the same string as the Display representation, but this is not a guarantee.)

Options currently supported:

§Example

use jiff::civil::time;

let t = time(7, 0, 0, 123_000_000);
assert_eq!(format!("{t:.6?}"), "07:00:00.123000");
// Precision values greater than 9 are clamped to 9.
assert_eq!(format!("{t:.300?}"), "07:00:00.123000000");
// A precision of 0 implies the entire fractional
// component is always truncated.
assert_eq!(format!("{t:.0?}"), "07:00:00");
Source§

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

Formats the value using the given formatter. Read more
Source§

impl Default for Time

Source§

fn default() -> Time

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for Time

Source§

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

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Display for Time

Converts a Time into an ISO 8601 compliant string.

Options currently supported:

§Example

use jiff::civil::time;

let t = time(7, 0, 0, 123_000_000);
assert_eq!(format!("{t:.6}"), "07:00:00.123000");
// Precision values greater than 9 are clamped to 9.
assert_eq!(format!("{t:.300}"), "07:00:00.123000000");
// A precision of 0 implies the entire fractional
// component is always truncated.
assert_eq!(format!("{t:.0}"), "07:00:00");
Source§

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

Formats the value using the given formatter. Read more
Source§

impl<'a> From<&'a Zoned> for Time

Source§

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

Converts to this type from the input type.
Source§

impl From<DateTime> for Time

Source§

fn from(dt: DateTime) -> Time

Converts to this type from the input type.
Source§

impl From<Time> for BrokenDownTime

Source§

fn from(t: Time) -> BrokenDownTime

Converts to this type from the input type.
Source§

impl From<Time> for Meridiem

Source§

fn from(t: Time) -> Meridiem

Converts to this type from the input type.
Source§

impl From<Time> for TimeDifference

Source§

fn from(time: Time) -> TimeDifference

Converts to this type from the input type.
Source§

impl From<Zoned> for Time

Source§

fn from(zdt: Zoned) -> Time

Converts to this type from the input type.
Source§

impl FromStr for Time

Source§

type Err = Error

The associated error which can be returned from parsing.
Source§

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

Parses a string s to return a value of this type. Read more
Source§

impl Hash for Time

Source§

fn hash<__H>(&self, state: &mut __H)
where __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl Ord for Time

Source§

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

This method returns an Ordering between self and other. Read more
1.21.0 · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

impl PartialEq for Time

Source§

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

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl PartialOrd for Time

Source§

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

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl Serialize for Time

Source§

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

Serialize this value into the given Serde serializer. Read more
Source§

impl Sub<Duration> for Time

Subtracts an unsigned duration of time. This uses wrapping arithmetic.

For checked arithmetic, see Time::checked_sub.

Source§

type Output = Time

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: Duration) -> Time

Performs the - operation. Read more
Source§

impl Sub<SignedDuration> for Time

Subtracts a signed duration of time. This uses wrapping arithmetic.

For checked arithmetic, see Time::checked_sub.

Source§

type Output = Time

The resulting type after applying the - operator.
Source§

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

Performs the - operation. Read more
Source§

impl Sub<Span> for Time

Subtracts a span of time. This uses wrapping arithmetic.

For checked arithmetic, see Time::checked_sub.

Source§

type Output = Time

The resulting type after applying the - operator.
Source§

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

Performs the - operation. Read more
Source§

impl Sub for Time

Computes the span of time between two times.

This will return a negative span when the time being subtracted is greater.

Since this uses the default configuration for calculating a span between two times (no rounding and largest units is hours), this will never panic or fail in any way.

To configure the largest unit or enable rounding, use Time::since.

Source§

type Output = Span

The resulting type after applying the - operator.
Source§

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

Performs the - operation. Read more
Source§

impl SubAssign<Duration> for Time

Subtracts an unsigned duration of time in place. This uses wrapping arithmetic.

For checked arithmetic, see Time::checked_sub.

Source§

fn sub_assign(&mut self, rhs: Duration)

Performs the -= operation. Read more
Source§

impl SubAssign<SignedDuration> for Time

Subtracts a signed duration of time in place. This uses wrapping arithmetic.

For checked arithmetic, see Time::checked_sub.

Source§

fn sub_assign(&mut self, rhs: SignedDuration)

Performs the -= operation. Read more
Source§

impl SubAssign<Span> for Time

Subtracts a span of time in place. This uses wrapping arithmetic.

For checked arithmetic, see Time::checked_sub.

Source§

fn sub_assign(&mut self, rhs: Span)

Performs the -= operation. Read more
Source§

impl Copy for Time

Source§

impl Eq for Time

Source§

impl StructuralPartialEq for Time

Auto Trait Implementations§

§

impl Freeze for Time

§

impl RefUnwindSafe for Time

§

impl Send for Time

§

impl Sync for Time

§

impl Unpin for Time

§

impl UnwindSafe for Time

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

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

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
Source§

impl<Q, K> Comparable<K> for Q
where Q: Ord + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

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

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize = _

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> QuickClone<T> for T
where T: Clone,

Source§

fn C(&self) -> T

Source§

impl<T> QuickToOwned for T
where T: ToOwned,

Source§

type Owned = <T as ToOwned>::Owned

Source§

fn O(&self) -> <T as QuickToOwned>::Owned

Source§

impl<T> QuickToString for T
where T: ToString + ?Sized,

Source§

fn S(&self) -> String

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

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

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

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

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> MaybeSendSync for T

Source§

impl<T> RuleType for T
where T: Copy + Debug + Eq + Hash + Ord,