Struct Time
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:
Time::wrapping_addorTime::wrapping_subfor wrapping arithmetic.Time::checked_addorTime::checked_subfor checked arithmetic.Time::saturating_addorTime::saturating_subfor saturating arithmetic.
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§
§impl Time
impl Time
pub fn new(
hour: i8,
minute: i8,
second: i8,
subsec_nanosecond: i32,
) -> Result<Time, Error>
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 <= 230 <= minute <= 590 <= second <= 590 <= 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());pub const fn constant(
hour: i8,
minute: i8,
second: i8,
subsec_nanosecond: i32,
) -> Time
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 <= 230 <= minute <= 590 <= second <= 590 <= 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);pub const fn midnight() -> Time
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);pub fn with(self) -> TimeWith
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));
pub fn hour(self) -> i8
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);pub fn minute(self) -> i8
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);pub fn second(self) -> i8
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);pub fn millisecond(self) -> i16
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);pub fn microsecond(self) -> i16
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);pub fn nanosecond(self) -> i16
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);pub fn subsec_nanosecond(self) -> i32
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::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);
pub const fn to_datetime(self, date: Date) -> DateTime
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));pub const fn on(self, year: i16, month: i8, day: i8) -> DateTime
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.
§Panics
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:
- The year must be in the range
-9999..=9999. - The month must be in the range
1..=12. - The day must be at least
1and must be at most the number of days in the corresponding month. So for example,2024-02-29is valid but2023-02-29is not.
Similarly, when used in a const context, invalid parameters will prevent your Rust program from compiling.
§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",
);pub fn wrapping_add<A>(self, duration: A) -> Timewhere
A: Into<TimeArithmetic>,
pub fn wrapping_add<A>(self, duration: A) -> Timewhere
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()));pub fn wrapping_sub<A>(self, duration: A) -> Timewhere
A: Into<TimeArithmetic>,
pub fn wrapping_sub<A>(self, duration: A) -> Timewhere
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),
);pub fn checked_add<A>(self, duration: A) -> Result<Time, Error>where
A: Into<TimeArithmetic>,
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));
pub fn checked_sub<A>(self, duration: A) -> Result<Time, Error>where
A: Into<TimeArithmetic>,
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),
);pub fn saturating_add<A>(self, duration: A) -> Timewhere
A: Into<TimeArithmetic>,
pub fn saturating_add<A>(self, duration: A) -> Timewhere
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()));pub fn saturating_sub<A>(self, duration: A) -> Timewhere
A: Into<TimeArithmetic>,
pub fn saturating_sub<A>(self, duration: A) -> Timewhere
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));
pub fn until<A>(self, other: A) -> Result<Span, Error>where
A: Into<TimeDifference>,
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");
pub fn since<A>(self, other: A) -> Result<Span, Error>where
A: Into<TimeDifference>,
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());pub fn duration_until(self, other: Time) -> SignedDuration
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());
pub fn duration_since(self, other: Time) -> SignedDuration
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)),
);pub fn round<R>(self, options: R) -> Result<Time, Error>where
R: Into<TimeRound>,
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 aTimeRound::new().smallest(unit)from the unit provided.From<(Unit, i64)> for Round, which will automatically create aTimeRound::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);
pub fn series(self, period: Span) -> TimeSeries
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),
]);§impl Time
Parsing and formatting using a “printf”-style API.
impl Time
Parsing and formatting using a “printf”-style API.
pub fn strptime(
format: impl AsRef<[u8]>,
input: impl AsRef<[u8]>,
) -> Result<Time, Error>
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");
pub fn strftime<'f, F>(&self, format: &'f F) -> Display<'f>
pub fn strftime<'f, F>(&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
This will never error or panic. In particular, lenient mode is enabled, which means that all possible strings have some non-error interpretation. Note that because of this, and since Jiff may add new conversion specifiers in the future, the behavior of a format string may change when it would otherwise be invalid.
To format in a way that surfaces errors, 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");
§Example: errors are silently ignored
If the formatting string is malformed in some way, then it is silently ignored. For example, when using an invalid formatting directive:
use jiff::civil::time;
let t = time(16, 30, 59, 0);
let string = t.strftime("%H %").to_string();
assert_eq!(string, "16 %");If one wants to surface errors from a formatting string, use a lower level API:
use jiff::civil::time;
let t = time(16, 30, 59, 0);
assert_eq!(
jiff::fmt::strtime::format("%H %", t).unwrap_err().to_string(),
"strftime formatting failed: invalid format string, \
expected byte after `%`, but found end of format string",
);impl Time
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§
§impl Add<Duration> for Time
Adds an unsigned duration of time. This uses wrapping arithmetic.
impl Add<Duration> for Time
Adds an unsigned duration of time. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_add.
§impl Add<SignedDuration> for Time
Adds a signed duration of time. This uses wrapping arithmetic.
impl Add<SignedDuration> for Time
Adds a signed duration of time. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_add.
§impl Add<Span> for Time
Adds a span of time. This uses wrapping arithmetic.
impl Add<Span> for Time
Adds a span of time. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_add.
§impl AddAssign<Duration> for Time
Adds an unsigned duration of time in place. This uses wrapping arithmetic.
impl AddAssign<Duration> for Time
Adds an unsigned duration of time in place. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_add.
§fn add_assign(&mut self, rhs: Duration)
fn add_assign(&mut self, rhs: Duration)
+= operation. Read more§impl AddAssign<SignedDuration> for Time
Adds a signed duration of time in place. This uses wrapping arithmetic.
impl AddAssign<SignedDuration> for Time
Adds a signed duration of time in place. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_add.
§fn add_assign(&mut self, rhs: SignedDuration)
fn add_assign(&mut self, rhs: SignedDuration)
+= operation. Read more§impl AddAssign<Span> for Time
Adds a span of time in place. This uses wrapping arithmetic.
impl AddAssign<Span> for Time
Adds a span of time in place. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_add.
§fn add_assign(&mut self, rhs: Span)
fn add_assign(&mut self, rhs: Span)
+= operation. Read more§impl Debug for Time
Converts a Time into a human readable time string.
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:
std::fmt::Formatter::precisioncan be set to control the precision of the fractional second component.
§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");
§impl Display for Time
Converts a Time into an ISO 8601 compliant string.
impl Display for Time
Converts a Time into an ISO 8601 compliant string.
§Formatting options supported
std::fmt::Formatter::precisioncan be set to control the precision of the fractional second component. When not set, the minimum precision required to losslessly render the value is used.
§Example
use jiff::civil::time;
// No fractional seconds:
let t = time(7, 0, 0, 0);
assert_eq!(format!("{t}"), "07:00:00");
// With fractional seconds:
let t = time(7, 0, 0, 123_000_000);
assert_eq!(format!("{t}"), "07:00:00.123");
§Example: setting the precision
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");
§impl Ord for Time
impl Ord for Time
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
§impl PartialOrd for Time
impl PartialOrd for Time
§impl Sub<Duration> for Time
Subtracts an unsigned duration of time. This uses wrapping arithmetic.
impl Sub<Duration> for Time
Subtracts an unsigned duration of time. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_sub.
§impl Sub<SignedDuration> for Time
Subtracts a signed duration of time. This uses wrapping arithmetic.
impl Sub<SignedDuration> for Time
Subtracts a signed duration of time. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_sub.
§impl Sub<Span> for Time
Subtracts a span of time. This uses wrapping arithmetic.
impl Sub<Span> for Time
Subtracts a span of time. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_sub.
§impl Sub for Time
Computes the span of time between two times.
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.
§impl SubAssign<Duration> for Time
Subtracts an unsigned duration of time in place. This uses wrapping
arithmetic.
impl SubAssign<Duration> for Time
Subtracts an unsigned duration of time in place. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_sub.
§fn sub_assign(&mut self, rhs: Duration)
fn sub_assign(&mut self, rhs: Duration)
-= operation. Read more§impl SubAssign<SignedDuration> for Time
Subtracts a signed duration of time in place. This uses wrapping arithmetic.
impl SubAssign<SignedDuration> for Time
Subtracts a signed duration of time in place. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_sub.
§fn sub_assign(&mut self, rhs: SignedDuration)
fn sub_assign(&mut self, rhs: SignedDuration)
-= operation. Read more§impl SubAssign<Span> for Time
Subtracts a span of time in place. This uses wrapping arithmetic.
impl SubAssign<Span> for Time
Subtracts a span of time in place. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_sub.
§fn sub_assign(&mut self, rhs: Span)
fn sub_assign(&mut self, rhs: Span)
-= operation. Read moreimpl Copy for Time
impl Eq for Time
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 UnsafeUnpin for Time
impl UnwindSafe for Time
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.