Struct Timestamp
pub struct Timestamp { /* private fields */ }
dep_jiff
and alloc
only.Expand description
An instant in time represented as the number of nanoseconds since the Unix epoch.
A timestamp is always in the Unix timescale with a UTC offset of zero.
To obtain civil or “local” datetime units like year, month, day or hour, a
timestamp needs to be combined with a TimeZone
to create a Zoned
.
That can be done with Timestamp::intz
or Timestamp::to_zoned
.
The integer count of nanoseconds since the Unix epoch is signed, where
the Unix epoch is 1970-01-01 00:00:00Z
. A positive timestamp indicates
a point in time after the Unix epoch. A negative timestamp indicates a
point in time before the Unix epoch.
§Parsing and printing
The Timestamp
type provides convenient trait implementations of
std::str::FromStr
and std::fmt::Display
:
use jiff::Timestamp;
let ts: Timestamp = "2024-06-19 15:22:45-04".parse()?;
assert_eq!(ts.to_string(), "2024-06-19T19:22:45Z");
A Timestamp
can also be parsed from something that contains a
timestamp, but with perhaps other data (such as a time zone):
use jiff::Timestamp;
let ts: Timestamp = "2024-06-19T15:22:45-04[America/New_York]".parse()?;
assert_eq!(ts.to_string(), "2024-06-19T19:22:45Z");
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 corresponds to 1970-01-01T00:00:00.000000000
. That is, it is the
Unix epoch. One can also access this value via the Timestamp::UNIX_EPOCH
constant.
§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 timestamp with a second
component of 60
, then it is automatically constrained to 59
:
use jiff::Timestamp;
let ts: Timestamp = "2016-12-31 23:59:60Z".parse()?;
assert_eq!(ts.to_string(), "2016-12-31T23:59:59Z");
§Comparisons
The Timestamp
type provides both Eq
and Ord
trait implementations
to facilitate easy comparisons. When a timestamp ts1
occurs before a
timestamp ts2
, then dt1 < dt2
. For example:
use jiff::Timestamp;
let ts1 = Timestamp::from_second(123_456_789)?;
let ts2 = Timestamp::from_second(123_456_790)?;
assert!(ts1 < ts2);
§Arithmetic
This type provides routines for adding and subtracting spans of time, as
well as computing the span of time between two Timestamp
values.
For adding or subtracting spans of time, one can use any of the following routines:
Timestamp::checked_add
orTimestamp::checked_sub
for checked arithmetic.Timestamp::saturating_add
orTimestamp::saturating_sub
for saturating arithmetic.
Additionally, checked arithmetic is available via the Add
and Sub
trait implementations. When the result overflows, a panic occurs.
use jiff::{Timestamp, ToSpan};
let ts1: Timestamp = "2024-02-25T15:45Z".parse()?;
let ts2 = ts1 - 24.hours();
assert_eq!(ts2.to_string(), "2024-02-24T15:45:00Z");
One can compute the span of time between two timestamps using either
Timestamp::until
or Timestamp::since
. It’s also possible to
subtract two Timestamp
values directly via a Sub
trait implementation:
use jiff::{Timestamp, ToSpan};
let ts1: Timestamp = "2024-05-03 23:30:00.123Z".parse()?;
let ts2: Timestamp = "2024-02-25 07Z".parse()?;
// The default is to return spans with units no bigger than seconds.
assert_eq!(ts1 - ts2, 5934600.seconds().milliseconds(123));
The until
and since
APIs are polymorphic and allow re-balancing and
rounding the span returned. For example, the default largest unit is
seconds (as exemplified above), but we can ask for bigger units (up to
hours):
use jiff::{Timestamp, ToSpan, Unit};
let ts1: Timestamp = "2024-05-03 23:30:00.123Z".parse()?;
let ts2: Timestamp = "2024-02-25 07Z".parse()?;
assert_eq!(
// If you want to deal in units bigger than hours, then you'll have to
// convert your timestamp to a [`Zoned`] first.
ts1.since((Unit::Hour, ts2))?,
1648.hours().minutes(30).milliseconds(123),
);
You can also round the span returned:
use jiff::{RoundMode, Timestamp, TimestampDifference, ToSpan, Unit};
let ts1: Timestamp = "2024-05-03 23:30:59.123Z".parse()?;
let ts2: Timestamp = "2024-05-02 07Z".parse()?;
assert_eq!(
ts1.since(
TimestampDifference::new(ts2)
.smallest(Unit::Minute)
.largest(Unit::Hour),
)?,
40.hours().minutes(30),
);
// `TimestampDifference` uses truncation as a rounding mode by default,
// but you can set the rounding mode to break ties away from zero:
assert_eq!(
ts1.since(
TimestampDifference::new(ts2)
.smallest(Unit::Minute)
.largest(Unit::Hour)
.mode(RoundMode::HalfExpand),
)?,
// Rounds up to 31 minutes.
40.hours().minutes(31),
);
§Rounding timestamps
A Timestamp
can be rounded based on a TimestampRound
configuration of
smallest units, rounding increment and rounding mode. Here’s an example
showing how to round to the nearest third hour:
use jiff::{Timestamp, TimestampRound, Unit};
let ts: Timestamp = "2024-06-19 16:27:29.999999999Z".parse()?;
assert_eq!(
ts.round(TimestampRound::new().smallest(Unit::Hour).increment(3))?,
"2024-06-19 15Z".parse::<Timestamp>()?,
);
// Or alternatively, make use of the `From<(Unit, i64)> for TimestampRound`
// trait implementation:
assert_eq!(
ts.round((Unit::Hour, 3))?.to_string(),
"2024-06-19T15:00:00Z",
);
See Timestamp::round
for more details.
§An instant in time
Unlike a civil::DateTime
, a Timestamp
always corresponds, unambiguously, to a precise instant in time (to
nanosecond precision). This means that attaching a time zone to a timestamp
is always unambiguous because there’s never any question as to which
instant it refers to. This is true even for gaps in civil time.
For example, in America/New_York
, clocks were moved ahead one hour
at clock time 2024-03-10 02:00:00
. That is, the 2 o’clock hour never
appeared on clocks in the America/New_York
region. Since parsing a
timestamp always requires an offset, the time it refers to is unambiguous.
We can see this by writing a clock time, 02:30
, that never existed but
with two different offsets:
use jiff::Timestamp;
// All we're doing here is attaching an offset to a civil datetime.
// There is no time zone information here, and thus there is no
// accounting for ambiguity due to daylight saving time transitions.
let before_hour_jump: Timestamp = "2024-03-10 02:30-04".parse()?;
let after_hour_jump: Timestamp = "2024-03-10 02:30-05".parse()?;
// This shows the instant in time in UTC.
assert_eq!(before_hour_jump.to_string(), "2024-03-10T06:30:00Z");
assert_eq!(after_hour_jump.to_string(), "2024-03-10T07:30:00Z");
// Now let's attach each instant to an `America/New_York` time zone.
let zdt_before = before_hour_jump.intz("America/New_York")?;
let zdt_after = after_hour_jump.intz("America/New_York")?;
// And now we can see that even though the original instant refers to
// the 2 o'clock hour, since that hour never existed on the clocks in
// `America/New_York`, an instant with a time zone correctly adjusts.
assert_eq!(
zdt_before.to_string(),
"2024-03-10T01:30:00-05:00[America/New_York]",
);
assert_eq!(
zdt_after.to_string(),
"2024-03-10T03:30:00-04:00[America/New_York]",
);
In the example above, there is never a step that is incorrect or has an
alternative answer. Every step is unambiguous because we never involve
any civil
datetimes.
But note that if the datetime string you’re parsing from lacks an offset, then it could be ambiguous even if a time zone is specified. In this case, parsing will always fail:
use jiff::Timestamp;
let result = "2024-06-30 08:30[America/New_York]".parse::<Timestamp>();
assert_eq!(
result.unwrap_err().to_string(),
"failed to find offset component in \
\"2024-06-30 08:30[America/New_York]\", \
which is required for parsing a timestamp",
);
§Converting a civil datetime to a timestamp
Sometimes you want to convert the “time on the clock” to a precise instant in time. One way to do this was demonstrated in the previous section, but it only works if you know your current time zone offset:
use jiff::Timestamp;
let ts: Timestamp = "2024-06-30 08:36-04".parse()?;
assert_eq!(ts.to_string(), "2024-06-30T12:36:00Z");
The above happened to be the precise instant in time I wrote the example.
Since I happened to know the offset, this worked okay. But what if I
didn’t? We could instead construct a civil datetime and attach a time zone
to it. This will create a Zoned
value, from which we can access the
timestamp:
use jiff::civil::date;
let clock = date(2024, 6, 30).at(8, 36, 0, 0).intz("America/New_York")?;
assert_eq!(clock.timestamp().to_string(), "2024-06-30T12:36:00Z");
Implementations§
§impl Timestamp
impl Timestamp
pub const MIN: Timestamp
pub const MIN: Timestamp
The minimum representable timestamp.
The minimum is chosen such that it can be combined with
any legal Offset
and turned into a
civil::DateTime
.
§Example
use jiff::{civil::date, tz::Offset, Timestamp};
let dt = Offset::MIN.to_datetime(Timestamp::MIN);
assert_eq!(dt, date(-9999, 1, 1).at(0, 0, 0, 0));
pub const MAX: Timestamp
pub const MAX: Timestamp
The maximum representable timestamp.
The maximum is chosen such that it can be combined with
any legal Offset
and turned into a
civil::DateTime
.
§Example
use jiff::{civil::date, tz::Offset, Timestamp};
let dt = Offset::MAX.to_datetime(Timestamp::MAX);
assert_eq!(dt, date(9999, 12, 31).at(23, 59, 59, 999_999_999));
pub const UNIX_EPOCH: Timestamp
pub const UNIX_EPOCH: Timestamp
The Unix epoch represented as a timestamp.
The Unix epoch corresponds to the instant at 1970-01-01T00:00:00Z
.
As a timestamp, it corresponds to 0
nanoseconds.
A timestamp is positive if and only if it is greater than the Unix epoch. A timestamp is negative if and only of it is less than the Unix epoch.
pub fn now() -> Timestamp
pub fn now() -> Timestamp
Returns the current system time as a timestamp.
§Panics
This panics if the system clock is set to a time value outside of the
range -009999-01-01T00:00:00Z..=9999-12-31T11:59:59.999999999Z
. The
justification here is that it is reasonable to expect the system clock
to be set to a somewhat sane, if imprecise, value.
If you want to get the current Unix time fallibly, use
Timestamp::try_from
with a std::time::SystemTime
as input.
This may also panic when SystemTime::now()
itself panics. The most
common context in which this happens is on the wasm32-unknown-unknown
target. If you’re using that target in the context of the web (for
example, via wasm-pack
), and you’re an application, then you should
enable Jiff’s js
feature. This will automatically instruct Jiff in
this very specific circumstance to execute JavaScript code to determine
the current time from the web browser.
§Example
use jiff::Timestamp;
assert!(Timestamp::now() > Timestamp::UNIX_EPOCH);
pub fn new(second: i64, nanosecond: i32) -> Result<Timestamp, Error> ⓘ
pub fn new(second: i64, nanosecond: i32) -> Result<Timestamp, Error> ⓘ
Creates a new instant in time represented as a timestamp.
While a timestamp is logically a count of nanoseconds since the Unix epoch, this constructor provides a convenience way of constructing the timestamp from two components: seconds and fractional seconds expressed as nanoseconds.
The signs of second
and nanosecond
need not be the same.
§Errors
This returns an error if the given components would correspond to
an instant outside the support ranged. Also, nanosecond
is limited
to the range -999,999,999..=999,999,999
.
§Example
This example shows the instant in time 123,456,789 seconds after the Unix epoch:
use jiff::Timestamp;
assert_eq!(
Timestamp::new(123_456_789, 0)?.to_string(),
"1973-11-29T21:33:09Z",
);
§Example: normalized sign
This example shows how second
and nanosecond
are resolved when
their signs differ.
use jiff::Timestamp;
let ts = Timestamp::new(2, -999_999_999)?;
assert_eq!(ts.as_second(), 1);
assert_eq!(ts.subsec_nanosecond(), 1);
let ts = Timestamp::new(-2, 999_999_999)?;
assert_eq!(ts.as_second(), -1);
assert_eq!(ts.subsec_nanosecond(), -1);
§Example: limits
The minimum timestamp has nanoseconds set to zero, while the maximum
timestamp has nanoseconds set to 999,999,999
:
use jiff::Timestamp;
assert_eq!(Timestamp::MIN.subsec_nanosecond(), 0);
assert_eq!(Timestamp::MAX.subsec_nanosecond(), 999_999_999);
As a consequence, nanoseconds cannot be negative when a timestamp has minimal seconds:
use jiff::Timestamp;
assert!(Timestamp::new(Timestamp::MIN.as_second(), -1).is_err());
// But they can be positive!
let one_ns_more = Timestamp::new(Timestamp::MIN.as_second(), 1)?;
assert_eq!(
one_ns_more.to_string(),
"-009999-01-02T01:59:59.000000001Z",
);
// Or, when combined with a minimal offset:
assert_eq!(
jiff::tz::Offset::MIN.to_datetime(one_ns_more).to_string(),
"-009999-01-01T00:00:00.000000001",
);
pub fn from_second(second: i64) -> Result<Timestamp, Error> ⓘ
pub fn from_second(second: i64) -> Result<Timestamp, Error> ⓘ
Creates a new instant in time from the number of seconds elapsed since the Unix epoch.
When second
is negative, it corresponds to an instant in time before
the Unix epoch. A smaller number corresponds to an instant in time
further into the past.
§Errors
This returns an error if the given second corresponds to a timestamp
outside of the Timestamp::MIN
and Timestamp::MAX
boundaries.
§Example
This example shows the instants in time 1 second immediately after and before the Unix epoch:
use jiff::Timestamp;
assert_eq!(
Timestamp::from_second(1)?.to_string(),
"1970-01-01T00:00:01Z",
);
assert_eq!(
Timestamp::from_second(-1)?.to_string(),
"1969-12-31T23:59:59Z",
);
pub fn from_millisecond(millisecond: i64) -> Result<Timestamp, Error> ⓘ
pub fn from_millisecond(millisecond: i64) -> Result<Timestamp, Error> ⓘ
Creates a new instant in time from the number of milliseconds elapsed since the Unix epoch.
When millisecond
is negative, it corresponds to an instant in time
before the Unix epoch. A smaller number corresponds to an instant in
time further into the past.
§Errors
This returns an error if the given millisecond corresponds to a
timestamp outside of the Timestamp::MIN
and Timestamp::MAX
boundaries.
§Example
This example shows the instants in time 1 millisecond immediately after and before the Unix epoch:
use jiff::Timestamp;
assert_eq!(
Timestamp::from_millisecond(1)?.to_string(),
"1970-01-01T00:00:00.001Z",
);
assert_eq!(
Timestamp::from_millisecond(-1)?.to_string(),
"1969-12-31T23:59:59.999Z",
);
pub fn from_microsecond(microsecond: i64) -> Result<Timestamp, Error> ⓘ
pub fn from_microsecond(microsecond: i64) -> Result<Timestamp, Error> ⓘ
Creates a new instant in time from the number of microseconds elapsed since the Unix epoch.
When microsecond
is negative, it corresponds to an instant in time
before the Unix epoch. A smaller number corresponds to an instant in
time further into the past.
§Errors
This returns an error if the given microsecond corresponds to a
timestamp outside of the Timestamp::MIN
and Timestamp::MAX
boundaries.
§Example
This example shows the instants in time 1 microsecond immediately after and before the Unix epoch:
use jiff::Timestamp;
assert_eq!(
Timestamp::from_microsecond(1)?.to_string(),
"1970-01-01T00:00:00.000001Z",
);
assert_eq!(
Timestamp::from_microsecond(-1)?.to_string(),
"1969-12-31T23:59:59.999999Z",
);
pub fn from_nanosecond(nanosecond: i128) -> Result<Timestamp, Error> ⓘ
pub fn from_nanosecond(nanosecond: i128) -> Result<Timestamp, Error> ⓘ
Creates a new instant in time from the number of nanoseconds elapsed since the Unix epoch.
When nanosecond
is negative, it corresponds to an instant in time
before the Unix epoch. A smaller number corresponds to an instant in
time further into the past.
§Errors
This returns an error if the given nanosecond corresponds to a
timestamp outside of the Timestamp::MIN
and Timestamp::MAX
boundaries.
§Example
This example shows the instants in time 1 nanosecond immediately after and before the Unix epoch:
use jiff::Timestamp;
assert_eq!(
Timestamp::from_nanosecond(1)?.to_string(),
"1970-01-01T00:00:00.000000001Z",
);
assert_eq!(
Timestamp::from_nanosecond(-1)?.to_string(),
"1969-12-31T23:59:59.999999999Z",
);
pub fn from_jiff_duration(duration: SignedDuration) -> Result<Timestamp, Error> ⓘ
pub fn from_jiff_duration(duration: SignedDuration) -> Result<Timestamp, Error> ⓘ
Creates a new timestamp from a Duration
with the given sign since the
Unix epoch.
Positive durations result in a timestamp after the Unix epoch. Negative durations result in a timestamp before the Unix epoch.
§Planned breaking change
It is planned to rename this routine to Timestamp::from_duration
in
jiff 0.2
. The current Timestamp::from_duration
routine, which
accepts a std::time::Duration
, will be removed. If callers need to
build a Timestamp
from a std::time::Duration
, then they should
first convert it to a SignedDuration
via
TryFrom<Duration> for SignedDuration
.
§Errors
This returns an error if the given duration corresponds to a timestamp
outside of the Timestamp::MIN
and Timestamp::MAX
boundaries.
§Example
How one might construct a Timestamp
from a SystemTime
:
use std::time::SystemTime;
use jiff::{SignedDuration, Timestamp};
let unix_epoch = SystemTime::UNIX_EPOCH;
let now = SystemTime::now();
let duration = SignedDuration::system_until(unix_epoch, now)?;
let ts = Timestamp::from_jiff_duration(duration)?;
assert!(ts > Timestamp::UNIX_EPOCH);
Of course, one should just use Timestamp::try_from
for this
instead. Indeed, the above example is copied almost exactly from the
TryFrom
implementation.
pub fn as_second(self) -> i64 ⓘ
pub fn as_second(self) -> i64 ⓘ
Returns this timestamp as a number of seconds since the Unix epoch.
This only returns the number of whole seconds. That is, if there are any fractional seconds in this timestamp, then they are truncated.
§Example
use jiff::Timestamp;
let ts = Timestamp::new(5, 123_456_789)?;
assert_eq!(ts.as_second(), 5);
let ts = Timestamp::new(5, 999_999_999)?;
assert_eq!(ts.as_second(), 5);
let ts = Timestamp::new(-5, -123_456_789)?;
assert_eq!(ts.as_second(), -5);
let ts = Timestamp::new(-5, -999_999_999)?;
assert_eq!(ts.as_second(), -5);
pub fn as_millisecond(self) -> i64 ⓘ
pub fn as_millisecond(self) -> i64 ⓘ
Returns this timestamp as a number of milliseconds since the Unix epoch.
This only returns the number of whole milliseconds. That is, if there are any fractional milliseconds in this timestamp, then they are truncated.
§Example
use jiff::Timestamp;
let ts = Timestamp::new(5, 123_456_789)?;
assert_eq!(ts.as_millisecond(), 5_123);
let ts = Timestamp::new(5, 999_999_999)?;
assert_eq!(ts.as_millisecond(), 5_999);
let ts = Timestamp::new(-5, -123_456_789)?;
assert_eq!(ts.as_millisecond(), -5_123);
let ts = Timestamp::new(-5, -999_999_999)?;
assert_eq!(ts.as_millisecond(), -5_999);
pub fn as_microsecond(self) -> i64 ⓘ
pub fn as_microsecond(self) -> i64 ⓘ
Returns this timestamp as a number of microseconds since the Unix epoch.
This only returns the number of whole microseconds. That is, if there are any fractional microseconds in this timestamp, then they are truncated.
§Example
use jiff::Timestamp;
let ts = Timestamp::new(5, 123_456_789)?;
assert_eq!(ts.as_microsecond(), 5_123_456);
let ts = Timestamp::new(5, 999_999_999)?;
assert_eq!(ts.as_microsecond(), 5_999_999);
let ts = Timestamp::new(-5, -123_456_789)?;
assert_eq!(ts.as_microsecond(), -5_123_456);
let ts = Timestamp::new(-5, -999_999_999)?;
assert_eq!(ts.as_microsecond(), -5_999_999);
pub fn as_nanosecond(self) -> i128 ⓘ
pub fn as_nanosecond(self) -> i128 ⓘ
Returns this timestamp as a number of nanoseconds since the Unix epoch.
Since a Timestamp
has a nanosecond precision, the nanoseconds
returned here represent this timestamp losslessly. That is, the
nanoseconds returned can be used with Timestamp::from_nanosecond
to
create an identical timestamp with no loss of precision.
§Example
use jiff::Timestamp;
let ts = Timestamp::new(5, 123_456_789)?;
assert_eq!(ts.as_nanosecond(), 5_123_456_789);
let ts = Timestamp::new(5, 999_999_999)?;
assert_eq!(ts.as_nanosecond(), 5_999_999_999);
let ts = Timestamp::new(-5, -123_456_789)?;
assert_eq!(ts.as_nanosecond(), -5_123_456_789);
let ts = Timestamp::new(-5, -999_999_999)?;
assert_eq!(ts.as_nanosecond(), -5_999_999_999);
pub fn subsec_millisecond(self) -> i32 ⓘ
pub fn subsec_millisecond(self) -> i32 ⓘ
Returns the fractional second component of this timestamp in units of milliseconds.
It is guaranteed that this will never return a value that is greater than 1 second (or less than -1 second).
This only returns the number of whole milliseconds. That is, if there are any fractional milliseconds in this timestamp, then they are truncated.
§Example
use jiff::Timestamp;
let ts = Timestamp::new(5, 123_456_789)?;
assert_eq!(ts.subsec_millisecond(), 123);
let ts = Timestamp::new(5, 999_999_999)?;
assert_eq!(ts.subsec_millisecond(), 999);
let ts = Timestamp::new(-5, -123_456_789)?;
assert_eq!(ts.subsec_millisecond(), -123);
let ts = Timestamp::new(-5, -999_999_999)?;
assert_eq!(ts.subsec_millisecond(), -999);
pub fn subsec_microsecond(self) -> i32 ⓘ
pub fn subsec_microsecond(self) -> i32 ⓘ
Returns the fractional second component of this timestamp in units of microseconds.
It is guaranteed that this will never return a value that is greater than 1 second (or less than -1 second).
This only returns the number of whole microseconds. That is, if there are any fractional microseconds in this timestamp, then they are truncated.
§Example
use jiff::Timestamp;
let ts = Timestamp::new(5, 123_456_789)?;
assert_eq!(ts.subsec_microsecond(), 123_456);
let ts = Timestamp::new(5, 999_999_999)?;
assert_eq!(ts.subsec_microsecond(), 999_999);
let ts = Timestamp::new(-5, -123_456_789)?;
assert_eq!(ts.subsec_microsecond(), -123_456);
let ts = Timestamp::new(-5, -999_999_999)?;
assert_eq!(ts.subsec_microsecond(), -999_999);
pub fn subsec_nanosecond(self) -> i32 ⓘ
pub fn subsec_nanosecond(self) -> i32 ⓘ
Returns the fractional second component of this timestamp in units of nanoseconds.
It is guaranteed that this will never return a value that is greater than 1 second (or less than -1 second).
§Example
use jiff::Timestamp;
let ts = Timestamp::new(5, 123_456_789)?;
assert_eq!(ts.subsec_nanosecond(), 123_456_789);
let ts = Timestamp::new(5, 999_999_999)?;
assert_eq!(ts.subsec_nanosecond(), 999_999_999);
let ts = Timestamp::new(-5, -123_456_789)?;
assert_eq!(ts.subsec_nanosecond(), -123_456_789);
let ts = Timestamp::new(-5, -999_999_999)?;
assert_eq!(ts.subsec_nanosecond(), -999_999_999);
pub fn as_jiff_duration(self) -> SignedDuration
pub fn as_jiff_duration(self) -> SignedDuration
Returns this timestamp as a SignedDuration
since the Unix epoch.
§Planned breaking change
It is planned to rename this routine to Timestamp::as_duration
in
jiff 0.2
. The current Timestamp::as_duration
routine, which returns
a std::time::Duration
, will be removed. If callers need a
std::time::Duration
from a Timestamp
, then they should call this
routine and then use TryFrom<SignedDuration> for Duration
to convert
the result.
§Example
use jiff::{SignedDuration, Timestamp};
assert_eq!(
Timestamp::UNIX_EPOCH.as_jiff_duration(),
SignedDuration::ZERO,
);
assert_eq!(
Timestamp::new(5, 123_456_789)?.as_jiff_duration(),
SignedDuration::new(5, 123_456_789),
);
assert_eq!(
Timestamp::new(-5, -123_456_789)?.as_jiff_duration(),
SignedDuration::new(-5, -123_456_789),
);
pub fn signum(self) -> i8 ⓘ
pub fn signum(self) -> i8 ⓘ
Returns the sign of this timestamp.
This can return one of three possible values:
0
when this timestamp is precisely equivalent toTimestamp::UNIX_EPOCH
.1
when this timestamp occurs after the Unix epoch.-1
when this timestamp occurs before the Unix epoch.
The sign returned is guaranteed to match the sign of all “getter”
methods on Timestamp
. For example, Timestamp::as_second
and
Timestamp::subsec_nanosecond
. This is true even if the signs
of the second
and nanosecond
components were mixed when given to
the Timestamp::new
constructor.
§Example
use jiff::Timestamp;
let ts = Timestamp::new(5, -999_999_999)?;
assert_eq!(ts.signum(), 1);
// The mixed signs were normalized away!
assert_eq!(ts.as_second(), 4);
assert_eq!(ts.subsec_nanosecond(), 1);
// The same applies for negative timestamps.
let ts = Timestamp::new(-5, 999_999_999)?;
assert_eq!(ts.signum(), -1);
assert_eq!(ts.as_second(), -4);
assert_eq!(ts.subsec_nanosecond(), -1);
pub fn is_zero(self) -> bool
pub fn is_zero(self) -> bool
Returns true if and only if this timestamp corresponds to the instant in time known as the Unix epoch.
§Example
use jiff::Timestamp;
assert!(Timestamp::UNIX_EPOCH.is_zero());
pub fn intz(self, time_zone_name: &str) -> Result<Zoned, Error> ⓘ
pub fn intz(self, time_zone_name: &str) -> Result<Zoned, Error> ⓘ
Creates a Zoned
value by attaching a time zone for the given name
to this instant in time.
The name given is resolved to a TimeZone
by using the default
TimeZoneDatabase
created by
tz::db
. Indeed, this is a convenience function
for Timestamp::to_zoned
where the time zone database lookup
is done automatically.
Assuming the time zone name could be resolved to a TimeZone
, this
routine is otherwise infallible and never results in any ambiguity
since both a Timestamp
and a Zoned
correspond to precise
instant in time. This is unlike
civil::DateTime::to_zoned
,
where a civil datetime might correspond to more than one instant in
time (i.e., a fold, typically DST ending) or no instants in time (i.e.,
a gap, typically DST starting).
§Errors
This returns an error when the given time zone name could not be found in the default time zone database.
§Example
This is a simple example of converting the instant that is 123,456,789
seconds after the Unix epoch to an instant that is aware of its time
zone:
use jiff::Timestamp;
let ts = Timestamp::new(123_456_789, 0).unwrap();
let zdt = ts.intz("America/New_York")?;
assert_eq!(zdt.to_string(), "1973-11-29T16:33:09-05:00[America/New_York]");
This can be used to answer questions like, “What time was it at the Unix epoch in Tasmania?”
use jiff::Timestamp;
// Time zone database lookups are case insensitive!
let zdt = Timestamp::UNIX_EPOCH.intz("australia/tasmania")?;
assert_eq!(zdt.to_string(), "1970-01-01T11:00:00+11:00[Australia/Tasmania]");
§Example: errors
This routine can return an error when the time zone is unrecognized:
use jiff::Timestamp;
assert!(Timestamp::UNIX_EPOCH.intz("does not exist").is_err());
pub fn to_zoned(self, tz: TimeZone) -> Zoned
pub fn to_zoned(self, tz: TimeZone) -> Zoned
Creates a Zoned
value by attaching the given time zone to this
instant in time.
This is infallible and never results in any ambiguity since both a
Timestamp
and a Zoned
correspond to precise instant in time.
This is unlike
civil::DateTime::to_zoned
,
where a civil datetime might correspond to more than one instant in
time (i.e., a fold, typically DST ending) or no instants in time (i.e.,
a gap, typically DST starting).
§Example
This example shows how to create a zoned value with a fixed time zone offset:
use jiff::{tz::{self, TimeZone}, Timestamp};
let ts = Timestamp::new(123_456_789, 0).unwrap();
let tz = TimeZone::fixed(tz::offset(-4));
let zdt = ts.to_zoned(tz);
// A time zone annotation is still included in the printable version
// of the Zoned value, but it is fixed to a particular offset.
assert_eq!(zdt.to_string(), "1973-11-29T17:33:09-04:00[-04:00]");
§Example: POSIX time zone strings
This example shows how to create a time zone from a POSIX time zone
string that describes the transition to and from daylight saving
time for America/St_Johns
. In particular, this rule uses non-zero
minutes, which is atypical.
use jiff::{tz::TimeZone, Timestamp};
let ts = Timestamp::new(123_456_789, 0)?;
let tz = TimeZone::posix("NST3:30NDT,M3.2.0,M11.1.0")?;
let zdt = ts.to_zoned(tz);
// There isn't any agreed upon mechanism for transmitting a POSIX time
// zone string within an RFC 9557 TZ annotation, so Jiff just emits the
// offset. In practice, POSIX TZ strings are rarely user facing anyway.
// (They are still in widespread use as an implementation detail of the
// IANA Time Zone Database however.)
assert_eq!(zdt.to_string(), "1973-11-29T18:03:09-03:30[-03:30]");
pub fn checked_add<A>(self, duration: A) -> Result<Timestamp, Error> ⓘwhere
A: Into<TimestampArithmetic>,
pub fn checked_add<A>(self, duration: A) -> Result<Timestamp, Error> ⓘwhere
A: Into<TimestampArithmetic>,
Add the given span of time to this timestamp.
This operation accepts three different duration types: Span
,
SignedDuration
or std::time::Duration
. This is achieved via
From
trait implementations for the TimestampArithmetic
type.
§Properties
Given a timestamp ts1
and a span s
, and assuming ts2 = ts1 + s
exists, it follows then that ts1 = ts2 - s
for all values of ts1
and s
that sum to a valid ts2
.
In short, subtracting the given span from the sum returned by this function is guaranteed to result in precisely the original timestamp.
§Errors
If the sum would overflow the minimum or maximum timestamp values, then an error is returned.
This also returns an error if the given duration is a Span
with any
non-zero units greater than hours. If you want to use bigger units,
convert this timestamp to a Zoned
and use Zoned::checked_add
.
This error occurs because a Timestamp
has no time zone attached to
it, and thus cannot unambiguously resolve the length of a single day.
§Example
This shows how to add 5
hours to the Unix epoch:
use jiff::{Timestamp, ToSpan};
let ts = Timestamp::UNIX_EPOCH.checked_add(5.hours())?;
assert_eq!(ts.to_string(), "1970-01-01T05:00:00Z");
§Example: negative spans are supported
This shows how to add -5
hours to the Unix epoch. This is the same
as subtracting 5
hours from the Unix epoch.
use jiff::{Timestamp, ToSpan};
let ts = Timestamp::UNIX_EPOCH.checked_add(-5.hours())?;
assert_eq!(ts.to_string(), "1969-12-31T19:00:00Z");
§Example: available via addition operator
This routine can be used via the +
operator. Note though that if it
fails, it will result in a panic.
use jiff::{Timestamp, ToSpan};
let ts1 = Timestamp::new(2_999_999_999, 0)?;
assert_eq!(ts1.to_string(), "2065-01-24T05:19:59Z");
let ts2 = ts1 + 1.hour().minutes(30).nanoseconds(123);
assert_eq!(ts2.to_string(), "2065-01-24T06:49:59.000000123Z");
§Example: error on overflow
use jiff::{Timestamp, ToSpan};
let ts = Timestamp::MAX;
assert_eq!(ts.to_string(), "9999-12-30T22:00:00.999999999Z");
assert!(ts.checked_add(1.nanosecond()).is_err());
let ts = Timestamp::MIN;
assert_eq!(ts.to_string(), "-009999-01-02T01:59:59Z");
assert!(ts.checked_add(-1.nanosecond()).is_err());
§Example: adding absolute durations
This shows how to add signed and unsigned absolute durations to a
Timestamp
.
use std::time::Duration;
use jiff::{SignedDuration, Timestamp};
let ts1 = Timestamp::new(2_999_999_999, 0)?;
assert_eq!(ts1.to_string(), "2065-01-24T05:19:59Z");
let dur = SignedDuration::new(60 * 60 + 30 * 60, 123);
assert_eq!(
ts1.checked_add(dur)?.to_string(),
"2065-01-24T06:49:59.000000123Z",
);
let dur = Duration::new(60 * 60 + 30 * 60, 123);
assert_eq!(
ts1.checked_add(dur)?.to_string(),
"2065-01-24T06:49:59.000000123Z",
);
pub fn checked_sub<A>(self, duration: A) -> Result<Timestamp, Error> ⓘwhere
A: Into<TimestampArithmetic>,
pub fn checked_sub<A>(self, duration: A) -> Result<Timestamp, Error> ⓘwhere
A: Into<TimestampArithmetic>,
This routine is identical to Timestamp::checked_add
with the
duration negated.
§Errors
This has the same error conditions as Timestamp::checked_add
.
§Example
This routine can be used via the -
operator. Note though that if it
fails, it will result in a panic.
use jiff::{SignedDuration, Timestamp, ToSpan};
let ts1 = Timestamp::new(2_999_999_999, 0)?;
assert_eq!(ts1.to_string(), "2065-01-24T05:19:59Z");
let ts2 = ts1 - 1.hour().minutes(30).nanoseconds(123);
assert_eq!(ts2.to_string(), "2065-01-24T03:49:58.999999877Z");
§Example: use with SignedDuration
and std::time::Duration
use std::time::Duration;
use jiff::{SignedDuration, Timestamp};
let ts1 = Timestamp::new(2_999_999_999, 0)?;
assert_eq!(ts1.to_string(), "2065-01-24T05:19:59Z");
let dur = SignedDuration::new(60 * 60 + 30 * 60, 123);
assert_eq!(
ts1.checked_sub(dur)?.to_string(),
"2065-01-24T03:49:58.999999877Z",
);
let dur = Duration::new(60 * 60 + 30 * 60, 123);
assert_eq!(
ts1.checked_sub(dur)?.to_string(),
"2065-01-24T03:49:58.999999877Z",
);
pub fn saturating_add<A>(self, duration: A) -> Timestampwhere
A: Into<TimestampArithmetic>,
pub fn saturating_add<A>(self, duration: A) -> Timestampwhere
A: Into<TimestampArithmetic>,
This routine is identical to Timestamp::checked_add
, except the
result saturates on overflow. That is, instead of overflow, either
Timestamp::MIN
or Timestamp::MAX
is returned.
§Panics
This panics if the given Span
contains any non-zero units greater
than hours. In jiff 0.2
, this panic will be changed to an error. It
panics in jiff 0.1
to avoid giving incorrect results. (It was an
oversight to make this method infallible.)
§Example
This example shows that arithmetic saturates on overflow.
use jiff::{SignedDuration, Timestamp, ToSpan};
assert_eq!(
Timestamp::MAX,
Timestamp::MAX.saturating_add(1.nanosecond()),
);
assert_eq!(
Timestamp::MIN,
Timestamp::MIN.saturating_add(-1.nanosecond()),
);
assert_eq!(
Timestamp::MAX,
Timestamp::UNIX_EPOCH.saturating_add(SignedDuration::MAX),
);
assert_eq!(
Timestamp::MIN,
Timestamp::UNIX_EPOCH.saturating_add(SignedDuration::MIN),
);
assert_eq!(
Timestamp::MAX,
Timestamp::UNIX_EPOCH.saturating_add(std::time::Duration::MAX),
);
pub fn saturating_sub<A>(self, duration: A) -> Timestampwhere
A: Into<TimestampArithmetic>,
pub fn saturating_sub<A>(self, duration: A) -> Timestampwhere
A: Into<TimestampArithmetic>,
This routine is identical to Timestamp::saturating_add
with the
span parameter negated.
§Panics
This routine panics under the same conditions as
Timestamp::saturating_add
.
§Example
This example shows that arithmetic saturates on overflow.
use jiff::{SignedDuration, Timestamp, ToSpan};
assert_eq!(
Timestamp::MIN,
Timestamp::MIN.saturating_sub(1.nanosecond()),
);
assert_eq!(
Timestamp::MAX,
Timestamp::MAX.saturating_sub(-1.nanosecond()),
);
assert_eq!(
Timestamp::MIN,
Timestamp::UNIX_EPOCH.saturating_sub(SignedDuration::MAX),
);
assert_eq!(
Timestamp::MAX,
Timestamp::UNIX_EPOCH.saturating_sub(SignedDuration::MIN),
);
assert_eq!(
Timestamp::MIN,
Timestamp::UNIX_EPOCH.saturating_sub(std::time::Duration::MAX),
);
pub fn until<A>(self, other: A) -> Result<Span, Error> ⓘwhere
A: Into<TimestampDifference>,
pub fn until<A>(self, other: A) -> Result<Span, Error> ⓘwhere
A: Into<TimestampDifference>,
Returns a span representing the elapsed time from this timestamp until
the given other
timestamp.
When other
occurs before this timestamp, then the span returned will
be negative.
Depending on the input provided, the span returned is rounded. It may also be balanced up to bigger units than the default. By default, the span returned is balanced such that the biggest possible unit is seconds.
This operation is configured by providing a TimestampDifference
value. Since this routine accepts anything that implements
Into<TimestampDifference>
, once can pass a Timestamp
directly.
One can also pass a (Unit, Timestamp)
, where Unit
is treated as
TimestampDifference::largest
.
§Properties
It is guaranteed that if the returned span is subtracted from other
,
and if no rounding is requested, then the original timestamp will be
returned.
This routine is equivalent to self.since(other).map(|span| -span)
if no rounding options are set. If rounding options are set, then
it’s equivalent to
self.since(other_without_rounding_options).map(|span| -span)
,
followed by a call to Span::round
with the appropriate rounding
options set. This is because the negation of a span can result in
different rounding results depending on the rounding mode.
§Errors
An error can occur in some cases when the requested configuration
would result in a span that is beyond allowable limits. For example,
the nanosecond component of a span cannot represent the span of
time between the minimum and maximum timestamps supported by Jiff.
Therefore, if one requests a span with its largest unit set to
Unit::Nanosecond
, then it’s possible for this routine to fail.
An error can also occur if TimestampDifference
is misconfigured. For
example, if the smallest unit provided is bigger than the largest unit,
or if the largest unit provided is bigger than hours. (To use bigger
units with an instant in time, use Zoned::until
instead.)
It is guaranteed that if one provides a timestamp with the default
TimestampDifference
configuration, then this routine will never
fail.
§Example
use jiff::{Timestamp, ToSpan};
let earlier: Timestamp = "2006-08-24T22:30:00Z".parse()?;
let later: Timestamp = "2019-01-31 21:00:00Z".parse()?;
assert_eq!(earlier.until(later)?, 392509800.seconds());
// Flipping the timestamps is fine, but you'll get a negative span.
assert_eq!(later.until(earlier)?, -392509800.seconds());
§Example: using bigger units
This example shows how to expand the span returned to bigger units.
This makes use of a From<(Unit, Timestamp)> for TimestampDifference
trait implementation.
use jiff::{Timestamp, ToSpan, Unit};
let ts1: Timestamp = "1995-12-07T03:24:30.000003500Z".parse()?;
let ts2: Timestamp = "2019-01-31 15:30:00Z".parse()?;
// The default limits durations to using "seconds" as the biggest unit.
let span = ts1.until(ts2)?;
assert_eq!(span.to_string(), "PT730641929.9999965S");
// But we can ask for units all the way up to hours.
let span = ts1.until((Unit::Hour, ts2))?;
assert_eq!(span.to_string(), "PT202956H5M29.9999965S");
§Example: rounding the result
This shows how one might find the difference between two timestamps and have the result rounded such that sub-seconds are removed.
In this case, we need to hand-construct a TimestampDifference
in order to gain full configurability.
use jiff::{Timestamp, TimestampDifference, ToSpan, Unit};
let ts1: Timestamp = "1995-12-07 03:24:30.000003500Z".parse()?;
let ts2: Timestamp = "2019-01-31 15:30:00Z".parse()?;
let span = ts1.until(
TimestampDifference::from(ts2).smallest(Unit::Second),
)?;
assert_eq!(span, 730641929.seconds());
// We can combine smallest and largest units too!
let span = ts1.until(
TimestampDifference::from(ts2)
.smallest(Unit::Second)
.largest(Unit::Hour),
)?;
assert_eq!(span, 202956.hours().minutes(5).seconds(29));
pub fn since<A>(self, other: A) -> Result<Span, Error> ⓘwhere
A: Into<TimestampDifference>,
pub fn since<A>(self, other: A) -> Result<Span, Error> ⓘwhere
A: Into<TimestampDifference>,
This routine is identical to Timestamp::until
, but the order of the
parameters is flipped.
§Errors
This has the same error conditions as Timestamp::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 timestamps, it will never panic.
use jiff::{Timestamp, ToSpan};
let earlier: Timestamp = "2006-08-24T22:30:00Z".parse()?;
let later: Timestamp = "2019-01-31 21:00:00Z".parse()?;
assert_eq!(later - earlier, 392509800.seconds());
pub fn duration_until(self, other: Timestamp) -> SignedDuration
pub fn duration_until(self, other: Timestamp) -> SignedDuration
Returns an absolute duration representing the elapsed time from this
timestamp until the given other
timestamp.
When other
occurs before this timestamp, then the duration returned
will be negative.
Unlike Timestamp::until
, this always returns a duration
corresponding to a 96-bit integer of nanoseconds between two
timestamps.
§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, Timestamp::until
can return an error in some cases due to misconfiguration. But like
this routine, Timestamp::until
never panics or returns an error in
its default configuration.
§When should I use this versus Timestamp::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 Timestamp::until
) unless you have
a specific reason to do otherwise.
§Example
use jiff::{Timestamp, SignedDuration};
let earlier: Timestamp = "2006-08-24T22:30:00Z".parse()?;
let later: Timestamp = "2019-01-31 21:00:00Z".parse()?;
assert_eq!(
earlier.duration_until(later),
SignedDuration::from_secs(392509800),
);
// Flipping the timestamps is fine, but you'll get a negative span.
assert_eq!(
later.duration_until(earlier),
SignedDuration::from_secs(-392509800),
);
§Example: difference with Timestamp::until
The primary difference between this routine and
Timestamp::until
, other than the return type, is that this
routine is likely to be faster. Namely, it does simple 96-bit
integer math, where as Timestamp::until
has to do a bit more
work to deal with the different types of units on a Span
.
Additionally, since the difference between two timestamps 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 Timestamp::until
. Because of this, one can always
convert between Span
and SignedDuration
as returned by methods
on Timestamp
without a relative datetime:
use jiff::{SignedDuration, Span, Timestamp};
let ts1: Timestamp = "2024-02-28T00:00:00Z".parse()?;
let ts2: Timestamp = "2024-03-01T00:00:00Z".parse()?;
let dur = ts1.duration_until(ts2);
// 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(172_800));
// 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::from_secs(172_800));
This conversion guarantee also applies to Timestamp::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.)
pub fn duration_since(self, other: Timestamp) -> SignedDuration
pub fn duration_since(self, other: Timestamp) -> SignedDuration
This routine is identical to Timestamp::duration_until
, but the
order of the parameters is flipped.
§Example
use jiff::{SignedDuration, Timestamp};
let earlier: Timestamp = "2006-08-24T22:30:00Z".parse()?;
let later: Timestamp = "2019-01-31 21:00:00Z".parse()?;
assert_eq!(
later.duration_since(earlier),
SignedDuration::from_secs(392509800),
);
pub fn round<R>(self, options: R) -> Result<Timestamp, Error> ⓘwhere
R: Into<TimestampRound>,
pub fn round<R>(self, options: R) -> Result<Timestamp, Error> ⓘwhere
R: Into<TimestampRound>,
Rounds this timestamp according to the TimestampRound
configuration
given.
The principal option is TimestampRound::smallest
, which allows
one to configure the smallest units in the returned timestamp.
Rounding is what determines whether the specified smallest unit
should keep its current value or whether it should be incremented.
Moreover, the amount it should be incremented can be configured via
TimestampRound::increment
. Finally, the rounding strategy itself
can be configured via TimestampRound::mode
.
Note that this routine is generic and accepts anything that
implements Into<TimestampRound>
. Some notable implementations are:
From<Unit> for TimestampRound
, which will automatically create aTimestampRound::new().smallest(unit)
from the unit provided.From<(Unit, i64)> for TimestampRound
, which will automatically create aTimestampRound::new().smallest(unit).increment(number)
from the unit and increment provided.
§Errors
This returns an error if the smallest unit configured on the given
TimestampRound
is bigger than hours.
The rounding increment, when combined with the smallest unit (which
defaults to Unit::Nanosecond
), must divide evenly into 86,400
seconds (one 24-hour civil day). For example, increments of both
45 seconds and 15 minutes are allowed, but 7 seconds and 25 minutes are
both not allowed.
§Example
This is a basic example that demonstrates rounding a timestamp to the
nearest hour. This also demonstrates calling this method with the
smallest unit directly, instead of constructing a TimestampRound
manually.
use jiff::{Timestamp, Unit};
let ts: Timestamp = "2024-06-19 15:30:00Z".parse()?;
assert_eq!(
ts.round(Unit::Hour)?.to_string(),
"2024-06-19T16:00:00Z",
);
let ts: Timestamp = "2024-06-19 15:29:59Z".parse()?;
assert_eq!(
ts.round(Unit::Hour)?.to_string(),
"2024-06-19T15:00:00Z",
);
§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::{RoundMode, Timestamp, TimestampRound, Unit};
// The default will round up to the next hour for any time past the
// 30 minute mark, but using truncation rounding will always round
// down.
let ts: Timestamp = "2024-06-19 15:30:00Z".parse()?;
assert_eq!(
ts.round(
TimestampRound::new()
.smallest(Unit::Hour)
.mode(RoundMode::Trunc),
)?.to_string(),
"2024-06-19T15:00:00Z",
);
§Example: rounding to the nearest 5 minute increment
use jiff::{Timestamp, Unit};
// rounds down
let ts: Timestamp = "2024-06-19T15:27:29.999999999Z".parse()?;
assert_eq!(
ts.round((Unit::Minute, 5))?.to_string(),
"2024-06-19T15:25:00Z",
);
// rounds up
let ts: Timestamp = "2024-06-19T15:27:30Z".parse()?;
assert_eq!(
ts.round((Unit::Minute, 5))?.to_string(),
"2024-06-19T15:30:00Z",
);
pub fn series(self, period: Span) -> TimestampSeries ⓘ
pub fn series(self, period: Span) -> TimestampSeries ⓘ
Return an iterator of periodic timestamps 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
Timestamp
value.
§Example: when to check a glucose monitor
When my cat had diabetes, my veterinarian installed a glucose monitor and instructed me to scan it about every 5 hours. This example lists all of the times I need to scan it for the 2 days following its installation:
use jiff::{Timestamp, ToSpan};
let start: Timestamp = "2023-07-15 16:30:00-04".parse()?;
let end = start.checked_add(48.hours())?;
let mut scan_times = vec![];
for ts in start.series(5.hours()).take_while(|&ts| ts <= end) {
scan_times.push(ts);
}
assert_eq!(scan_times, vec![
"2023-07-15 16:30:00-04:00".parse::<Timestamp>()?,
"2023-07-15 21:30:00-04:00".parse::<Timestamp>()?,
"2023-07-16 02:30:00-04:00".parse::<Timestamp>()?,
"2023-07-16 07:30:00-04:00".parse::<Timestamp>()?,
"2023-07-16 12:30:00-04:00".parse::<Timestamp>()?,
"2023-07-16 17:30:00-04:00".parse::<Timestamp>()?,
"2023-07-16 22:30:00-04:00".parse::<Timestamp>()?,
"2023-07-17 03:30:00-04:00".parse::<Timestamp>()?,
"2023-07-17 08:30:00-04:00".parse::<Timestamp>()?,
"2023-07-17 13:30:00-04:00".parse::<Timestamp>()?,
]);
§impl Timestamp
Parsing and formatting APIs.
impl Timestamp
Parsing and formatting APIs.
pub fn strptime(
format: impl AsRef<[u8]>,
input: impl AsRef<[u8]>,
) -> Result<Timestamp, Error> ⓘ
pub fn strptime( format: impl AsRef<[u8]>, input: impl AsRef<[u8]>, ) -> Result<Timestamp, Error> ⓘ
Parses a timestamp (expressed as broken down 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 timestamp. For example, if an offset wasn’t parsed. (The offset is needed to turn the civil time parsed into a precise instant in time.)
§Example
This example shows how to parse a datetime string into a timestamp:
use jiff::Timestamp;
let ts = Timestamp::strptime("%F %H:%M %:z", "2024-07-14 21:14 -04:00")?;
assert_eq!(ts.to_string(), "2024-07-15T01:14:00Z");
pub fn strftime<'f, F>(&self, format: &'f F) -> Display<'f>
pub fn strftime<'f, F>(&self, format: &'f F) -> Display<'f>
Formats this timestamp 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 shows how to format a timestamp into a human readable datetime in UTC:
use jiff::{civil::date, Timestamp};
let ts = Timestamp::from_second(86_400)?;
let string = ts.strftime("%a %b %e %I:%M:%S %p UTC %Y").to_string();
assert_eq!(string, "Fri Jan 2 12:00:00 AM UTC 1970");
pub fn display_with_offset(&self, offset: Offset) -> TimestampDisplayWithOffset
pub fn display_with_offset(&self, offset: Offset) -> TimestampDisplayWithOffset
Format a Timestamp
datetime into a string with the given offset.
This will format to an RFC 3339 compatible string with an offset.
This will never use either Z
(for Zulu time) or -00:00
as an
offset. This is because Zulu time (and -00:00
) mean “the time in UTC
is known, but the offset to local time is unknown.” Since this routine
accepts an explicit offset, the offset is known. For example,
Offset::UTC
will be formatted as +00:00
.
To format an RFC 3339 string in Zulu time, use the default
std::fmt::Display
trait implementation on Timestamp
.
§Example
use jiff::{tz, Timestamp};
let ts = Timestamp::from_second(1)?;
assert_eq!(
ts.display_with_offset(tz::offset(-5)).to_string(),
"1969-12-31T19:00:01-05:00",
);
§impl Timestamp
Deprecated APIs on Timestamp
.
impl Timestamp
Deprecated APIs on Timestamp
.
pub fn from_duration(duration: Duration) -> Result<Timestamp, Error> ⓘ
👎Deprecated since 0.1.5: use Timestamp::from_jiff_duration instead
pub fn from_duration(duration: Duration) -> Result<Timestamp, Error> ⓘ
Creates a new instant from a Duration
since the Unix epoch.
A Duration
is always positive. If you need to construct
a timestamp before the Unix epoch with a Duration
, use
Timestamp::from_signed_duration
.
§Errors
This returns an error if the given duration corresponds to a timestamp
greater than Timestamp::MAX
.
§Example
How one might construct a Timestamp
from a SystemTime
if one can
assume the time is after the Unix epoch:
use std::time::SystemTime;
use jiff::Timestamp;
let elapsed = SystemTime::UNIX_EPOCH.elapsed()?;
assert!(Timestamp::from_duration(elapsed).is_ok());
Of course, one should just use Timestamp::try_from
for this
instead.
pub fn from_signed_duration(
sign: i8,
duration: Duration,
) -> Result<Timestamp, Error> ⓘ
👎Deprecated since 0.1.5: use Timestamp::from_jiff_duration instead
pub fn from_signed_duration( sign: i8, duration: Duration, ) -> Result<Timestamp, Error> ⓘ
Creates a new timestamp from a Duration
with the given sign since the
Unix epoch.
Positive durations result in a timestamp after the Unix epoch. Negative durations result in a timestamp before the Unix epoch.
§Errors
This returns an error if the given duration corresponds to a timestamp
outside of the Timestamp::MIN
and Timestamp::MAX
boundaries.
§Example
How one might construct a Timestamp
from a SystemTime
:
use std::time::SystemTime;
use jiff::Timestamp;
let unix_epoch = SystemTime::UNIX_EPOCH;
let now = SystemTime::now();
let (duration, sign) = match now.duration_since(unix_epoch) {
Ok(duration) => (duration, 1),
Err(err) => (err.duration(), -1),
};
let ts = Timestamp::from_signed_duration(sign, duration)?;
assert!(ts > Timestamp::UNIX_EPOCH);
§Example: a sign of 0 always results in Timestamp::UNIX_EPOCH
use jiff::Timestamp;
let duration = std::time::Duration::new(5, 123_456_789);
let ts = Timestamp::from_signed_duration(0, duration)?;
assert_eq!(ts, Timestamp::UNIX_EPOCH);
pub fn as_duration(self) -> (i8, Duration) ⓘ
👎Deprecated since 0.1.5: use Timestamp::as_jiff_duration instead
pub fn as_duration(self) -> (i8, Duration) ⓘ
Returns this timestamp as a standard library
Duration
since the Unix epoch.
Since a Duration
is unsigned and a Timestamp
is signed, this
also returns the sign of this timestamp (-1
, 0
or 1
) along with
the unsigned Duration
. A negative sign means the duration should be
subtracted from the Unix epoch. A positive sign means the duration
should be added to the Unix epoch. A zero sign means the duration is
the same precise instant as the Unix epoch.
§Example
use std::time::Duration;
use jiff::Timestamp;
assert_eq!(
Timestamp::UNIX_EPOCH.as_duration(),
(0, Duration::ZERO),
);
assert_eq!(
Timestamp::new(5, 123_456_789)?.as_duration(),
(1, Duration::new(5, 123_456_789)),
);
assert_eq!(
Timestamp::new(-5, -123_456_789)?.as_duration(),
(-1, Duration::new(5, 123_456_789)),
);
impl Timestamp
Internal APIs using Jiff ranged integers.
Trait Implementations§
§impl Add<Duration> for Timestamp
Adds an unsigned duration of time to a timestamp.
impl Add<Duration> for Timestamp
Adds an unsigned duration of time to a timestamp.
This uses checked arithmetic and panics on overflow. To handle overflow
without panics, use Timestamp::checked_add
.
§impl Add<SignedDuration> for Timestamp
Adds a signed duration of time to a timestamp.
impl Add<SignedDuration> for Timestamp
Adds a signed duration of time to a timestamp.
This uses checked arithmetic and panics on overflow. To handle overflow
without panics, use Timestamp::checked_add
.
§impl Add<Span> for Timestamp
Adds a span of time to a timestamp.
impl Add<Span> for Timestamp
Adds a span of time to a timestamp.
This uses checked arithmetic and panics when it fails. To handle arithmetic
without panics, use Timestamp::checked_add
. Note that the failure
condition includes overflow and using a Span
with non-zero units greater
than hours.
§impl AddAssign<Duration> for Timestamp
Adds an unsigned duration of time to a timestamp in place.
impl AddAssign<Duration> for Timestamp
Adds an unsigned duration of time to a timestamp in place.
This uses checked arithmetic and panics on overflow. To handle overflow
without panics, use Timestamp::checked_add
.
§fn add_assign(&mut self, rhs: Duration)
fn add_assign(&mut self, rhs: Duration)
+=
operation. Read more§impl AddAssign<SignedDuration> for Timestamp
Adds a signed duration of time to a timestamp in place.
impl AddAssign<SignedDuration> for Timestamp
Adds a signed duration of time to a timestamp in place.
This uses checked arithmetic and panics on overflow. To handle overflow
without panics, use Timestamp::checked_add
.
§fn add_assign(&mut self, rhs: SignedDuration)
fn add_assign(&mut self, rhs: SignedDuration)
+=
operation. Read more§impl AddAssign<Span> for Timestamp
Adds a span of time to a timestamp in place.
impl AddAssign<Span> for Timestamp
Adds a span of time to a timestamp in place.
This uses checked arithmetic and panics when it fails. To handle arithmetic
without panics, use Timestamp::checked_add
. Note that the failure
condition includes overflow and using a Span
with non-zero units greater
than hours.
§fn add_assign(&mut self, rhs: Span)
fn add_assign(&mut self, rhs: Span)
+=
operation. Read more§impl Debug for Timestamp
Converts a Timestamp
datetime into a human readable datetime string.
impl Debug for Timestamp
Converts a Timestamp
datetime into a human readable datetime 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::Timestamp;
let ts = Timestamp::new(1_123_456_789, 123_000_000)?;
assert_eq!(
format!("{ts:.6?}"),
"2005-08-07T23:19:49.123000Z",
);
// Precision values greater than 9 are clamped to 9.
assert_eq!(
format!("{ts:.300?}"),
"2005-08-07T23:19:49.123000000Z",
);
// A precision of 0 implies the entire fractional
// component is always truncated.
assert_eq!(
format!("{ts:.0?}"),
"2005-08-07T23:19:49Z",
);
§impl Display for Timestamp
Converts a Timestamp
datetime into a RFC 3339 compliant string.
impl Display for Timestamp
Converts a Timestamp
datetime into a RFC 3339 compliant string.
Since a Timestamp
never has an offset associated with it and is always
in UTC, the string emitted by this trait implementation uses Z
for “Zulu”
time. The significance of Zulu time is prescribed by RFC 9557 and means
that “the time in UTC is known, but the offset to local time is unknown.”
If you need to emit an RFC 3339 compliant string with a specific offset,
then use Timestamp::display_with_offset
.
§Forrmatting options supported
std::fmt::Formatter::precision
can be set to control the precision of the fractional second component.
§Example
use jiff::Timestamp;
let ts = Timestamp::new(1_123_456_789, 123_000_000)?;
assert_eq!(
format!("{ts:.6}"),
"2005-08-07T23:19:49.123000Z",
);
// Precision values greater than 9 are clamped to 9.
assert_eq!(
format!("{ts:.300}"),
"2005-08-07T23:19:49.123000000Z",
);
// A precision of 0 implies the entire fractional
// component is always truncated.
assert_eq!(
format!("{ts:.0}"),
"2005-08-07T23:19:49Z",
);
§impl From<Timestamp> for BrokenDownTime
impl From<Timestamp> for BrokenDownTime
§fn from(ts: Timestamp) -> BrokenDownTime
fn from(ts: Timestamp) -> BrokenDownTime
§impl From<Timestamp> for SystemTime
impl From<Timestamp> for SystemTime
§fn from(time: Timestamp) -> SystemTime
fn from(time: Timestamp) -> SystemTime
§impl From<Timestamp> for TimestampDifference
impl From<Timestamp> for TimestampDifference
§fn from(ts: Timestamp) -> TimestampDifference
fn from(ts: Timestamp) -> TimestampDifference
§impl Ord for Timestamp
impl Ord for Timestamp
§impl PartialOrd for Timestamp
impl PartialOrd for Timestamp
§impl Sub<Duration> for Timestamp
Subtracts an unsigned duration of time from a timestamp.
impl Sub<Duration> for Timestamp
Subtracts an unsigned duration of time from a timestamp.
This uses checked arithmetic and panics on overflow. To handle overflow
without panics, use Timestamp::checked_sub
.
§impl Sub<SignedDuration> for Timestamp
Subtracts a signed duration of time from a timestamp.
impl Sub<SignedDuration> for Timestamp
Subtracts a signed duration of time from a timestamp.
This uses checked arithmetic and panics on overflow. To handle overflow
without panics, use Timestamp::checked_sub
.
§impl Sub<Span> for Timestamp
Subtracts a span of time from a timestamp.
impl Sub<Span> for Timestamp
Subtracts a span of time from a timestamp.
This uses checked arithmetic and panics when it fails. To handle arithmetic
without panics, use Timestamp::checked_sub
. Note that the failure
condition includes overflow and using a Span
with non-zero units greater
than hours.
§impl Sub for Timestamp
Computes the span of time between two timestamps.
impl Sub for Timestamp
Computes the span of time between two timestamps.
This will return a negative span when the timestamp being subtracted is greater.
Since this uses the default configuration for calculating a span between two timestamps (no rounding and largest units is seconds), this will never panic or fail in any way.
To configure the largest unit or enable rounding, use Timestamp::since
.
§impl SubAssign<Duration> for Timestamp
Subtracts an unsigned duration of time from a timestamp in place.
impl SubAssign<Duration> for Timestamp
Subtracts an unsigned duration of time from a timestamp in place.
This uses checked arithmetic and panics on overflow. To handle overflow
without panics, use Timestamp::checked_sub
.
§fn sub_assign(&mut self, rhs: Duration)
fn sub_assign(&mut self, rhs: Duration)
-=
operation. Read more§impl SubAssign<SignedDuration> for Timestamp
Subtracts a signed duration of time from a timestamp in place.
impl SubAssign<SignedDuration> for Timestamp
Subtracts a signed duration of time from a timestamp in place.
This uses checked arithmetic and panics on overflow. To handle overflow
without panics, use Timestamp::checked_sub
.
§fn sub_assign(&mut self, rhs: SignedDuration)
fn sub_assign(&mut self, rhs: SignedDuration)
-=
operation. Read more§impl SubAssign<Span> for Timestamp
Subtracts a span of time from a timestamp in place.
impl SubAssign<Span> for Timestamp
Subtracts a span of time from a timestamp in place.
This uses checked arithmetic and panics when it fails. To handle arithmetic
without panics, use Timestamp::checked_sub
. Note that the failure
condition includes overflow and using a Span
with non-zero units greater
than hours.
§fn sub_assign(&mut self, rhs: Span)
fn sub_assign(&mut self, rhs: Span)
-=
operation. Read more§impl TryFrom<SystemTime> for Timestamp
impl TryFrom<SystemTime> for Timestamp
impl Copy for Timestamp
impl Eq for Timestamp
Auto Trait Implementations§
impl Freeze for Timestamp
impl RefUnwindSafe for Timestamp
impl Send for Timestamp
impl Sync for Timestamp
impl Unpin for Timestamp
impl UnwindSafe for Timestamp
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.