Struct Time
pub struct Time { /* private fields */ }
dep_jiff
and alloc
only.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));
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(),
);
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(),
);
// `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(),
);
§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 <= 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());
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 <= 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);
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::{civil, Timestamp};
// 1,234 nanoseconds after the Unix epoch.
let zdt = Timestamp::new(0, 1_234)?.intz("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)?.intz("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.
§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));
// Flipping the dates is fine, but you'll get a negative span.
assert_eq!(t2.until(t1)?, -2.seconds().milliseconds(500));
§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));
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));
// 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> ⓘ
pub fn round<R>(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);
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
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");
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::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");
§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.
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");
§impl From<Time> for BrokenDownTime
impl From<Time> for BrokenDownTime
§fn from(t: Time) -> BrokenDownTime
fn from(t: Time) -> BrokenDownTime
§impl From<Time> for TimeDifference
impl From<Time> for TimeDifference
§fn from(time: Time) -> TimeDifference
fn from(time: Time) -> TimeDifference
§impl Ord for Time
impl Ord for Time
§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 UnwindSafe for Time
Blanket Implementations§
§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
§type ArchivedMetadata = ()
type ArchivedMetadata = ()
§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
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> ByteSized for T
impl<T> ByteSized for T
Source§const BYTE_ALIGN: usize = _
const BYTE_ALIGN: usize = _
Source§fn byte_align(&self) -> usize ⓘ
fn byte_align(&self) -> usize ⓘ
Source§fn ptr_size_ratio(&self) -> [usize; 2]
fn ptr_size_ratio(&self) -> [usize; 2]
Source§impl<T, R> Chain<R> for Twhere
T: ?Sized,
impl<T, R> Chain<R> for Twhere
T: ?Sized,
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.Source§impl<T> ExtAny for T
impl<T> ExtAny for T
Source§fn as_any_mut(&mut self) -> &mut dyn Anywhere
Self: Sized,
fn as_any_mut(&mut self) -> &mut dyn Anywhere
Self: Sized,
Source§impl<T> ExtMem for Twhere
T: ?Sized,
impl<T> ExtMem for Twhere
T: ?Sized,
Source§const NEEDS_DROP: bool = _
const NEEDS_DROP: bool = _
Source§fn mem_align_of_val(&self) -> usize ⓘ
fn mem_align_of_val(&self) -> usize ⓘ
Source§fn mem_size_of_val(&self) -> usize ⓘ
fn mem_size_of_val(&self) -> usize ⓘ
Source§fn mem_needs_drop(&self) -> bool
fn mem_needs_drop(&self) -> bool
true
if dropping values of this type matters. Read moreSource§fn mem_forget(self)where
Self: Sized,
fn mem_forget(self)where
Self: Sized,
self
without running its destructor. Read moreSource§fn mem_replace(&mut self, other: Self) -> Selfwhere
Self: Sized,
fn mem_replace(&mut self, other: Self) -> Selfwhere
Self: Sized,
Source§unsafe fn mem_zeroed<T>() -> T
unsafe fn mem_zeroed<T>() -> T
unsafe_layout
only.T
represented by the all-zero byte-pattern. Read moreSource§unsafe fn mem_transmute_copy<Src, Dst>(src: &Src) -> Dst
unsafe fn mem_transmute_copy<Src, Dst>(src: &Src) -> Dst
unsafe_layout
only.T
represented by the all-zero byte-pattern. Read moreSource§fn mem_as_bytes(&self) -> &[u8] ⓘ
fn mem_as_bytes(&self) -> &[u8] ⓘ
unsafe_slice
only.§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T> Hook for T
impl<T> Hook for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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§impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
§impl<T> LayoutRaw for T
impl<T> LayoutRaw for T
§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError> ⓘ
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError> ⓘ
§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out
indicating that a T
is niched.