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_add
orTime::wrapping_sub
for wrapping arithmetic.Time::checked_add
orTime::checked_sub
for checked arithmetic.Time::saturating_add
orTime::saturating_sub
for 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§
Source§impl Time
impl Time
Sourcepub const MIN: Time = _
pub const MIN: Time = _
The minimum representable time value.
This corresponds to 00:00:00.000000000
.
Sourcepub const MAX: Time = _
pub const MAX: Time = _
The maximum representable time value.
This corresponds to 23:59:59.999999999
.
Sourcepub 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 <= 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());
Sourcepub 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 <= 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);
Sourcepub 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);
Sourcepub 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));
Sourcepub 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);
Sourcepub 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);
Sourcepub 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);
Sourcepub 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);
Sourcepub 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);
Sourcepub 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);
Sourcepub 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::{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);
Sourcepub 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));
Sourcepub 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.
§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",
);
Sourcepub fn wrapping_add<A: Into<TimeArithmetic>>(self, duration: A) -> Time
pub fn wrapping_add<A: Into<TimeArithmetic>>(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()));
Sourcepub fn wrapping_sub<A: Into<TimeArithmetic>>(self, duration: A) -> Time
pub fn wrapping_sub<A: Into<TimeArithmetic>>(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),
);
Sourcepub fn checked_add<A: Into<TimeArithmetic>>(
self,
duration: A,
) -> Result<Time, Error>
pub fn checked_add<A: Into<TimeArithmetic>>( 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())?,
);
§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));
Sourcepub fn checked_sub<A: Into<TimeArithmetic>>(
self,
duration: A,
) -> Result<Time, Error>
pub fn checked_sub<A: Into<TimeArithmetic>>( 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),
);
Sourcepub fn saturating_add<A: Into<TimeArithmetic>>(self, duration: A) -> Time
pub fn saturating_add<A: Into<TimeArithmetic>>(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));
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()));
Sourcepub fn saturating_sub<A: Into<TimeArithmetic>>(self, duration: A) -> Time
pub fn saturating_sub<A: Into<TimeArithmetic>>(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));
Sourcepub fn until<A: Into<TimeDifference>>(self, other: A) -> Result<Span, Error>
pub fn until<A: Into<TimeDifference>>(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());
§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");
Sourcepub fn since<A: Into<TimeDifference>>(self, other: A) -> Result<Span, Error>
pub fn since<A: Into<TimeDifference>>(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());
Sourcepub 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());
Sourcepub 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)),
);
Sourcepub fn round<R: Into<TimeRound>>(self, options: R) -> Result<Time, Error>
pub fn round<R: Into<TimeRound>>(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 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);
Sourcepub 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),
]);
Source§impl Time
impl Time
Parsing and formatting using a “printf”-style API.
Sourcepub 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");
Sourcepub fn strftime<'f, F: 'f + ?Sized + AsRef<[u8]>>(
&self,
format: &'f F,
) -> Display<'f>
pub fn strftime<'f, F: 'f + ?Sized + AsRef<[u8]>>( &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");
Trait Implementations§
Source§impl Add<Duration> for Time
impl Add<Duration> for Time
Adds an unsigned duration of time. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_add
.
Source§impl Add<SignedDuration> for Time
impl Add<SignedDuration> for Time
Adds a signed duration of time. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_add
.
Source§impl Add<Span> for Time
impl Add<Span> for Time
Adds a span of time. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_add
.
Source§impl AddAssign<Duration> for Time
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: UnsignedDuration)
fn add_assign(&mut self, rhs: UnsignedDuration)
+=
operation. Read moreSource§impl AddAssign<SignedDuration> for Time
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)
fn add_assign(&mut self, rhs: SignedDuration)
+=
operation. Read moreSource§impl AddAssign<Span> for Time
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)
fn add_assign(&mut self, rhs: Span)
+=
operation. Read moreSource§impl Debug for Time
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::precision
can 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");
Source§impl<'de> Deserialize<'de> for Time
impl<'de> Deserialize<'de> for Time
Source§fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Time, D::Error>
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Time, D::Error>
Source§impl Display for Time
impl Display for Time
Converts a Time
into an ISO 8601 compliant string.
Options currently supported:
std::fmt::Formatter::precision
can 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");
Source§impl From<Time> for BrokenDownTime
impl From<Time> for BrokenDownTime
Source§fn from(t: Time) -> BrokenDownTime
fn from(t: Time) -> BrokenDownTime
Source§impl From<Time> for TimeDifference
impl From<Time> for TimeDifference
Source§fn from(time: Time) -> TimeDifference
fn from(time: Time) -> TimeDifference
Source§impl Ord for Time
impl Ord for Time
Source§impl PartialOrd for Time
impl PartialOrd for Time
Source§impl Sub<Duration> for Time
impl Sub<Duration> for Time
Subtracts an unsigned duration of time. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_sub
.
Source§impl Sub<SignedDuration> for Time
impl Sub<SignedDuration> for Time
Subtracts a signed duration of time. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_sub
.
Source§impl Sub<Span> for Time
impl Sub<Span> for Time
Subtracts a span of time. This uses wrapping arithmetic.
For checked arithmetic, see Time::checked_sub
.
Source§impl Sub for Time
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§impl SubAssign<Duration> for Time
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: UnsignedDuration)
fn sub_assign(&mut self, rhs: UnsignedDuration)
-=
operation. Read moreSource§impl SubAssign<SignedDuration> for Time
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)
fn sub_assign(&mut self, rhs: SignedDuration)
-=
operation. Read moreSource§impl SubAssign<Span> for Time
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)
fn sub_assign(&mut self, rhs: Span)
-=
operation. Read more