NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #533 most downloaded on crates.io
A date-time library that encourages you to jump into the pit of success. This library is heavily inspired by the Temporal project.
Last release today
06 Oct 2026
Ships fairly regularly
a new release about every 3 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
1 version withdrawn
withdrawn after publishing
3 years old
70 releases · first in 2024
This release updates Jiff's bundled copy of the [IANA Time Zone Database] to 2026e. See the [2026e release announcement] for more details.
This release updates Jiff's bundled copy of the [IANA Time Zone Database]
to 2026e. See the 2026e release announcement for more details.
This is a redux release of 0.2.36 that fixes a compilation bug.
This is a redux release of 0.2.36 that fixes a compilation bug.
Bug fixes:
One column per month.
This release has a couple bug fixes and adds opt-in integration with the arbitrary crate.
This release has a couple bug fixes and adds opt-in integration with the
arbitrary crate.
Enhancements:
Arbitrary trait implementations from the arbitrary crate.Bug fixes:
This release fixes a bug in duration parsing where, e.g., -PT0.5S would be parsed as if the - sign didn't exist. This bug also affects friendly durati
This release fixes a bug in duration parsing where, e.g., -PT0.5S would be
parsed as if the - sign didn't exist. This bug also affects friendly
durations such as -0.5s.
Bug fixes:
This release contains a few small enhancements. Namely, some error messages for parsing datetime values have been improved by removing some redundant
This release contains a few small enhancements. Namely, some error messages
for parsing datetime values have been improved by removing some redundant
messaging. Additionally, the strftime APIs on datetime values can no longer
panic. Instead, they'll silently pass through invalid formatting directives.
Enhancements:
This release permits the use of a global time zone database in alloc-only environments. It also contains a massive internal refactor that introduces a
This release permits the use of a global time zone database in alloc-only
environments. It also contains a massive internal refactor that introduces a
new jiff-core crate for better code sharing.
Enhancements:
This release updates Jiff's bundled copy of the [IANA Time Zone Database] to 2026c. See the [2026c release announcement] for more details.
This release updates Jiff's bundled copy of the [IANA Time Zone Database]
to 2026c. See the 2026c release announcement for more details.
This release fixes a minor bug in tests that prevents the crate from running through standard build processes in Linux distributions downstream.
This release fixes a minor bug in tests that prevents the crate from running through standard build processes in Linux distributions downstream.
This release fixes a safety soundness bug in Jiff's lower level printing APIs. There is also a nice performance improvement to civil::Date::weekday, w
This release fixes a safety soundness bug in Jiff's lower level printing
APIs. There is also a nice performance improvement to civil::Date::weekday,
which also improves downstread routines like civil::Date::nth_weekday and
datetime<-->timestamp conversions in some cases.
Enhancements:
Bug fixes:
String destination buffer
with lower level printing APIs inside of jiff::fmt.This release adds support for [defmt], which is a highly efficient logging framework that targets resource-constrained devices, like microcontrollers.
This release adds support for [defmt], which is a highly efficient logging
framework that targets resource-constrained devices, like microcontrollers.
Enhancements:
defmt crate by implementing defmt::Format on the
principle public types in Jiff.Zoned::UNIX_EPOCH as a constant.Debug output for civil::ISOWeekDate to match the Debug output
style of other primitive datetime types.Bug fixes:
This is a small release with a fix for test failures on 32-bit targets in no-alloc environments.
This is a small release with a fix for test failures on 32-bit targets in
no-alloc environments.
Bug fixes:
no-alloc environments.This is a small release with a bug fix for build errors on Windows for very old versions of Rust.
This is a small release with a bug fix for build errors on Windows for very old versions of Rust.
Bug fixes:
This release has a couple enhancements.
This release has a couple enhancements.
Firstly, Jiff now uses windows-link for calling FFI routines on Windows
instead of windows-sys. Using windows-link means less churn and fewer
duplicates in the dependency graph.
Secondly, a new jiff-sqlx 0.2.0 release has been put out to support
sqlx 0.9.0.
Enhancements:
windows-sys with windows-link and inline bindings.jiff-sqlx to use sqlx 0.9.0 and release jiff-sqlx 0.2.0.Bug fixes:
RoundMode.This release updates Jiff's bundled copy of the [IANA Time Zone Database] to 2026b. See the [2026b release announcement] for more details.
This release updates Jiff's bundled copy of the [IANA Time Zone Database]
to 2026b. See the 2026b release announcement for more details.
This release primarily adds a new memory_usage routine for reporting heap allocation sizes for the TimeZone and Zoned types. This release also acknowl
This release primarily adds a new memory_usage routine for reporting
heap allocation sizes for the TimeZone and Zoned types. This
release also acknowledges and updates the timeline expectations for a
Jiff 1.0 release in README.md.
Enhancements:
memory_usage to the TimeZone and Zoned types.Span::checked_add example.Bug fixes:
This release updates Jiff's bundled copy of the [IANA Time Zone Database] to 2026a. See the [2026a release announcement] for more details.
This release updates Jiff's bundled copy of the [IANA Time Zone Database]
to 2026a. See the 2026a release announcement for more details.
This release includes a bug fix where fallible conversions from signed durations to unsigned durations could panic in some cases.
This release includes a bug fix where fallible conversions from signed durations to unsigned durations could panic in some cases.
Bug fixes:
std::time::Duration::try_from(SignedDuration::new(0, -1)).This release contains a performance improvement and a bug fix for civil::Date::new where it could panic on some inputs.
This release contains a performance improvement and a bug fix for
civil::Date::new where it could panic on some inputs.
Bug fixes:
Date::new could panic. This was a regression introduced in
jiff 0.2.20.Performance:
Timestamp to civil::DateTime conversion performance by ~15%.This release contains a major internal refactor that moves off of using ranged integers internally. There are also some small bug fixes and added supp
This release contains a major internal refactor that moves off of using ranged integers internally. There are also some small bug fixes and added support for finding the system time zone on emscripten targets.
Enhancements:
time crate in the Jiff documentation.Bug fixes:
This is a small release with a performance optimization (with respect to doing heavily contended arithmetic on Zoned values) and a bug fix for a panic
This is a small release with a performance optimization (with respect to doing
heavily contended arithmetic on Zoned values) and a bug fix for a panic
that can occur when using %2s in strftime.
Enhancements:
TimeZone for consuming operations on Zoned.Bug fixes:
timestamp.strftime("%2s").This release ships a sizeable refactor to the RFC 2822, RFC 9110, RC 3339, RFC 9557, ISO 8601 and friendly format printers. Specifically, they are now
This release ships a sizeable refactor to the RFC 2822, RFC 9110, RC
3339, RFC 9557, ISO 8601 and friendly format printers. Specifically,
they are now all monomorphic internally (instead of being generic over
jiff::fmt::Write) and write to uninitialized buffers. This improves
runtime performance (sometimes dramatically so), and to a more modest
degree, decreases binary size and improves compile times.
This release also includes a bug fix where DateTime::MIN.to_zoned(..)
could panic.
Enhancements:
jiff::SignedDuration.strftime
implementation.civil::DateTime::MIN could panic.(For example, some binary size improvements may require minor API breaking changes.)
This release contains binary size improvements to Jiff, more succinct error messages and some new minor APIs.
While Jiff 1.0 is overdue, I've been doing a lot of experimenting with improving Jiff's binary size and compile times. In particular, I want to spend time doing this before Jiff 1.0 so that we don't box ourselves into a corner. (For example, some binary size improvements may require minor API breaking changes.)
In this release, Jiff has switched to structured error handling internally in an effort to provide error predicates and also hopefully improve binary sizes and compile times. Overall this didn't have as big of an impact on binary sizes or compile times as I was hoping. I did take this opportunity to make Jiff's error messages a bit more succinct. In many cases, this involved de-duplicating some aspects of error messages and omitting user provided input in the messages. If you feel like there is a significant decrease in error message quality that isn't easily amended by callers providing additional context themselves, please open an issue.
This release also updates Jiff's bundled copy of the [IANA Time Zone Database]
to 2025c. See the 2025c release announcement for more details.
Enhancements:
Display, FromStr, Serialize and Deserialize trait implementations
for jiff::civil::ISOWeekDate. These all use the ISO 8601 week date format.jiff::Error for basic error introspection.This release contains a number of enhancements and bug fixes that have accrued over the last few months. Most are small polishes. A couple of the bug
This release contains a number of enhancements and bug fixes that have accrued
over the last few months. Most are small polishes. A couple of the bug fixes
apply to panics that could occur when parsing invalid TZ strings or invalid
strptime format strings.
Also, parsing into a Span should now be much faster (for both the ISO 8601
and "friendly" duration formats).
Enhancements:
std::time::Duration values.Sub and Add trait implementations for Zoned (in addition to the
already existing trait implementations for &Zoned).BrokenDownTime::set_meridiem and ensure it overrides the hour when
formatting.serde to serde_core. This should help speed up
compilation times in some cases.Zoned::series API, making it consistent with the same API on other
datetime types.lenient mode is enabled for strftime, Jiff will no longer error when
the formatting string contains invalid UTF-8.%y and %g no longer fails based on the specific year value.%s is now a bit more consistent with other fields. Moreover,
BrokenDownTime::{to_timestamp,to_zoned} will now prefer timestamps parsed
with %s over any other fields that have been parsed.%s into a Zoned via the Etc/Unknown time zone.Bug fixes:
2087-12-31T23:00:00Z in the Africa/Casablanca time zone
could not be round-tripped (because its offset was calculated incorrectly as
a result of not handling "permanent DST" POSIX time zones).%: via strptime APIs.TimeZone::unknown()
is a fallback for TimeZone::system() (instead of the jiff 0.1 behavior of
using TimeZone::UTC).%C) via strptime.-9223372036854775808s
and -PT9223372036854775808S.Performance:
Span or SignedDuration is now a fair bit faster in some cases.This release fixes a bug where error values were being constructed during parsing even in the success case. This was a regression introduced in 0.2.14
This release fixes a bug where error values were being constructed during
parsing even in the success case. This was a regression introduced in 0.2.14
as a result of trying to improve compilation times. Thankfully, fixing this
regression doesn't seem to meaningfully impact the amount of IR generated by
compiling Jiff.
Bug fixes:
This release includes a smattering of bug fixes, and hopefully a small improvement to the time it takes to compile Jiff. Also, in this release, when T
This release includes a smattering of bug fixes, and hopefully a small
improvement to the time it takes to compile Jiff. Also, in this release, when
TZ is set to a non-empty but invalid value, Jiff will always fall back to
Etc/Unknown when using TimeZone::system(). This differs from previous
behavior where Jiff would, in this case, attempt to read the system's default
time zone. This change brings Jiff into consistency with existing Unix tooling
like date, and is also arguably a better failure mode. That is, when TZ is
set but invalid, we shouldn't silently fall back to the default system time
zone, but instead do something that indicates something has potentially gone
wrong.
Enhancements:
Bug fixes:
This release fixes a bug in a corner case where TimeZone::following could sometimes omit the last time zone transition. This could only happen in time
This release fixes a bug in a corner case where TimeZone::following could
sometimes omit the last time zone transition. This could only happen in time
zones that once had daylight saving time, but ended it. This did not have an
impact on other Jiff APIs that handle daylight saving time.
Bug fixes:
TimeZone::following could omit the last historical time zone
transition.This release fixes a couple bugs in Jiff's parser. In particular, a regression was introduced in jiff 0.2.11 where its RFC 2822 parser could panic on
This release fixes a couple bugs in Jiff's parser. In particular, a regression
was introduced in jiff 0.2.11 where its RFC 2822 parser could panic on some
inputs. Previous releases of Jiff are unaffected.
Bug fixes:
This release includes new APIs for customizing Jiff's strtime behavior along with a few minor bug fixes. Jiff's strtime formatting API has also been o
This release includes new APIs for customizing Jiff's strtime behavior along
with a few minor bug fixes. Jiff's strtime formatting API has also been
optimized. It's about twice as fast as it was.
This release also coincides with the publication of jiff-icu 0.2.0-beta.2,
which has support for icu 2.0.0-beta.2.
Enhancements:
%c, %r, %X and %x conversion specifiers.%q in jiff::fmt::strtime (prints quarter of year).%::z and %:::z in jiff::fmt::strtime.%N in jiff::fmt::strtime (alias for %9f).strtime formatting APIs that ignores most errors.Bug fixes:
Display impls for datetime types.TimeZone::get("UTC") should now always return TimeZone::UTC.Performance:
strftime APIs are now approximately twice as fast as they were.
Performance should be comparable to chrono and time's prebuilt APIs.This release includes a bug fix for parsing Tuesday when using %A via Jiff's strptime APIs. Specifically, it would recognize Tueday instead of Tuesday
This release includes a bug fix for parsing Tuesday when using %A via
Jiff's strptime APIs. Specifically, it would recognize Tueday instead of
Tuesday.
Bug fixes:
strptime parsing from Tueday to Tuesday.This release includes a bug fix that, in debug mode, could result in datetime types having different hashes for the same value. This could cause probl
This release includes a bug fix that, in debug mode, could result in datetime types having different hashes for the same value. This could cause problems, for example, if you are using datetimes as keys in a hash map. This problem didn't exist when Jiff was compiled in release mode.
This release also improves the panic message shown when the js feature isn't
enabled and the current time is requested on wasm32-unknown-unknown targets.
Enhancements:
Zoned::now() fails on WASM.Bug fixes:
Hash on datetime types could yield different hash values for
the same underlying date/time.This release fixes a bug where the constructors on SignedDuration for floating point durations could panic (in debug mode) or produce incorrect result
This release fixes a bug where the constructors on SignedDuration
for floating point durations could panic (in debug mode) or produce
incorrect results (in release mode). This bug only impacts users of
the try_from_secs_{f32,f64} and from_secs_{f32,f64} methods on
SignedDuration.
Enhancements:
Debug impl for SignedDuration that only shows its second
and nanosecond components (while using only one component when the other is
zero).Bug fixes:
SignedDuration::(try_)?from_secs_{f32,f64}.This release includes a bug fix that changes how an empty but set TZ environment variable is interpreted (as indistinguishable from TZ=UTC). This also
This release includes a bug fix that changes how an empty but set TZ
environment variable is interpreted (as indistinguishable from TZ=UTC).
This also includes a new enabled by default create feature, perf-inline,
which allows toggling Jiff's use of inline(always). This may help improve
compile times or decrease binary size.
Enhancements:
perf-inline crate feature for controlling inline(always) annotations.Bug fixes:
TZ= indistinguishable from TZ=UTC.This release includes a few bug fixes and support for discovering the IANA Time Zone Database automatically on Illumos.
This release includes a few bug fixes and support for discovering the IANA Time Zone Database automatically on Illumos.
Enhancements:
Bug fixes:
This release updates Jiff's bundled copy of the [IANA Time Zone Database] to 2025b. See the [2025b release announcement] for more details.
This release updates Jiff's bundled copy of the [IANA Time Zone Database] to
2025b. See the 2025b release announcement for more details.
Enhancements:
jiff-tzdb to 2025b.This is another small release that fixes a problem where Jiff could break builds if they relied on inference for integer comparisons. Specifically, Ji
This is another small release that fixes a problem where Jiff could break builds if they relied on inference for integer comparisons. Specifically, Jiff uses internal trait impls to make comparing its internal ranged integers more convenient. But Rust the language has no concept of "internal" trait impls, and thus this can impact type inference. If code was written in a way that relies on a singular trait impl that is available, then adding Jiff to the project can cause it to break.
This isn't arguably Jiff's fault per se, but since these trait impls were just about internal convenience and not essential to Jiff's design, we adopt a pragmatic approach and just remove them.
Bug fixes:
This is a small release that fixes a bug in the handling of POSIX time zones in some cases. Specifically, the implementation of Date::yesterday was wr
This is a small release that fixes a bug in the handling of POSIX time zones
in some cases. Specifically, the implementation of Date::yesterday was wrong
when the date was the first of the month. This was a regression introduced in
0.2.2 and was not present in older releases. More test coverage has been
added.
Bug fixes:
Date::yesterday.This release of Jiff includes a new opt-in proc macro for embedding a TimeZone into your binary. Just enable Jiff's static feature, and this will prin
This release of Jiff includes a new opt-in proc macro for embedding a
TimeZone into your binary. Just enable Jiff's static feature, and this will
print the current time in the America/New_York time zone:
use jiff::{
tz::{self, TimeZone},
Timestamp,
};
fn main() {
static TZ: TimeZone = tz::get!("America/New_York");
let zdt = Timestamp::now().to_zoned(TZ.clone());
println!("{zdt}");
}
This enables TimeZone to be meaningfully used in core-only environments,
even when dynamic memory allocation isn't available.
This release also features a number of performance improvements for time zone lookups. In some cases, the improvement is significant (by an order of magnitude).
Additionally, the IANA Time Zone Database embedded into jiff-tzdb now
uses "rearguard" semantics. This means that the boolean flag indicating
whether daylight saving time is active or not (only accessible via
TimeZone::to_offset_info) will respect the actual definition of
daylight saving time. (This is relevant, for example, for time zones like
Europe/Dublin, where their summer time is legally known as their standard
time, but is in effect daylight saving time.)
Enhancements:
tz::{get,include} macros for time zone support in core-only environments.rearguard tzdb data in jiff-tzdb and document it.jiff-tzdb.jiff-sqlx and jiff-diesel.Timestamp constructors.Bug fixes:
ZonedWith::nanosecond and
ZonedWith::subsec_nanosecond.This release includes a massive number of optimizations that significantly improves performance in some cases. If you had a workload whose performance
This release includes a massive number of optimizations that significantly improves performance in some cases. If you had a workload whose performance with Jiff was underwhelming, please give it a try. I welcome questions via [Discussions on GitHub].
This release also provides a new API, Timestamp::constant, for constructing
Timestamp values in a const context.
Enhancements:
This is a new semver incompatible release of Jiff. It contains several breaking changes. I expect most users of Jiff to be able to upgrade without any…
This is a new semver incompatible release of Jiff. It contains several breaking changes. I expect most users of Jiff to be able to upgrade without any changes. The fundamental API organization of Jiff has not changed.
Some of the highlights of this release include reducing footguns and better ecosystem integration.
For reducing footguns, APIs on Span will no longer implicitly assume that
days are always 24 hours long. And Span no longer implements PartialEq or
Eq (instead favoring span.fieldwise() to create a value that supports naive
fieldwise comparison). Moreover, when using TimeZone::system() (perhaps via
Zoned::now()), if the system time zone could not be detected, then a special
Etc/Unknown time zone will be used instead. This avoids erroring, but also
surfaces itself to make it clearer that something has (perhaps) gone wrong.
As for ecosystem integration, this release coincides with the publication
of the [jiff-icu], [jiff-sqlx] and [jiff-diesel] crates. jiff-icu
integrates with the [ICU4X project], and is now the recommended way to use
Jiff to work with non-Gregorian calendars or to localize datetimes for end
users. jiff-sqlx and jiff-diesel provide wrapper types that implement the
necessary traits to make it ergonomic to store and retrieve Jiff values in a
database using [SQLx] or [Diesel], respectively.
Unless something unexpected happens, my plan is for the next breaking change release to be Jiff 1.0 in about 6 months. Once Jiff 1.0 is out, I plan to commit to it indefinitely.
BREAKING CHANGES:
This is an exhaustive list of breaking changes. Changes with the bolded RUNTIME prefix are changes that will not be caught by the Rust compiler. That is, they are changes in runtime behavior.
intz routines on Zoned, Timestamp, civil::DateTime and
civil::Date have been removed. You can use in_tz instead. This change was
made because many found the name intz to be unclear.PartialEq and Eq trait implementations on Span have been removed.
Ideally these shouldn't have been used, but if you do need them, please use
Span::fieldwise to create a SpanFieldwise, which does have the PartialEq
and Eq traits implemented. These were removed on Span itself because they
made it very easy to commit subtle bugs.Timestamp::saturing_add into errors. Callers adding
spans that are known to contain units of hours or smaller are guaranteed that
this will not return an error.Span APIs, days are no longer silently assumed to always be 24 hours when
a relative datetime is not provided. Instead, to perform operations on units
of days or bigger, callers must either provide a relative date or opt into
invariant 24-hour days with SpanRelativeTo::days_are_24_hours. Shortcuts have
been added to the span builders. For example, SpanTotal::days_are_24_hours.%V conversion specifier in
jiff::fmt::strtime from formatting an IANA time zone identifier to formatting
an ISO 8601 week number. To format an IANA time zone identifier, use %Q or
%:Q (which were introduced in jiff 0.1).Zoned with a civil time corresponding to a gap, we treat
all offsets as invalid and return an error. Previously, we would accept the
offset as given. This brings us into line with Temporal's behavior. For
example, previously Jiff accepted 2006-04-02T02:30-05[America/Indiana/Vevay]
but will now return an error. This is desirable for cases where a datetime in
the future is serialized before a change in the daylight saving time rules.
For more examples, see jiff::fmt::temporal::DateTimeParser::offset_conflict
for details on how to change Jiff's default behavior. This behavior change also
applies to tz::OffsetConflict::PreferOffset.tz::TimeZoneDatabase so that it only initializes one
internal tzdb instead of trying to find as many as possible. It is unlikely
that you'll be impacted by this change, but it's meant to make the semantics
be a bit more sensible. (In jiff 0.1, it was in theory possible for one tz
lookup to succeed in the system zoneinfo and then another tz lookup to fail
in zoneinfo but succeed automatically via the bundled copy. But this seems
confusing and possibly not desirable. Hence the change.)Zoned
and civil::Date, the civil::Date::to_iso_week_date and
civil::ISOWeekDate::to_date APIs were renamed to civil::Date::iso_week_date
and civil::ISOWeekDate::date.Span::to_duration for converting a Span to a std::time::Duration
and rename Span::to_jiff_duration to Span::to_duration. This prioritizes
SignedDuration as the "primary" non-calendar duration type in Jiff. And makes
it more consistent with APIs like Zoned::duration_since. For non-calendar
spans, the TryFrom<Span> for std::time::Duration still exists. For calendar
durations, use Span::to_duration and then convert the SignedDuration to
std::time::Duration. Additionally, Timestamp::from_jiff_duration and
Timestamp::as_jiff_duration were renamed to Timestamp::from_duration and
Timestamp::as_duration, respectively. The old deprecated routines on the
unsigned std::time::Duration have been removed.jiff::tz::TimeZoneNameIter
iterator from String to jiff::tz::TimeZoneName. This opaque type is more
API evolution friendly. To access the string, either use TimeZoneName's
Display trait implementation, or its as_str method.TimeZone::to_offset into two methods. One that just returns the
offset, and another, TimeZone::to_offset_info, which includes the offset,
DST status and time zone abbreviation. The extra info is rarely needed and
is sometimes more costly to compute. Also, make the lifetime of the time
zone abbreviation returned by TimeZoneTransition::abbreviation tied to
the transition instead of the time zone (for future API flexibility, likely
in core-only environments). This change was overall motivated by wanting to
do less work in the common case (where we only need the offset), and for
reducing the size of a TimeZone considerably in core-only environments.
Callers previously using TimeZone::to_offset to get DST status and time zone
abbreviation should now use TimeZone::to_offset_info.TimeZone::system() cannot find a system configured time zone, jiff 0.1 would automatically fall back to TimeZone::UTC (with a WARN-level log
message). In jiff 0.2, the fall back is now to TimeZone::unknown(), which
has a special Etc/Unknown identifier (as specified by Unicode and reserved by
the IANA time zone database). The fallback otherwise still behaves as if it
were TimeZone::UTC. This helps surface error conditions related to finding
the system time zone without causing unrecoverable failure.Enhancements:
SpanRelativeTo::days_are_24_hours() marker is used, weeks
will also be treated as invariant. That is, seven 24-hour days. In all cases,
working with years and months still requires a relative date.tzdb-bundle-always crate feature and explicitly creating a
jiff::tz::TimeZoneDatabase::bundled() database. Once in hand, you must use
APIs like TimeZoneDatabase::get to create a TimeZone and avoid any APIs
that implicitly use the global time zone database (like Timestamp::in_tz or
even Zoned::from_str).jiff-icu] crate. jiff-icu
provides traits for easily converting between datetime types defined in Jiff
and datetime types defined in ICU4X.jiff-sqlx] crate. jiff-sqlx
provides wrapper types that implement the necessary traits in SQLx for
reasonably ergonomic integration. This includes PostgreSQL and SQLite support,
but not MySQL support. (It's not clear if it's possible at present to provide
MySQL support for SQLx for datetime types outside of SQLx itself.)jiff-diesel] crate.
jiff-diesel provides wrapper types that implement the necessary traits in
Diesel for reasonably ergonomic integration. This includes MySQL, PostgreSQL
and SQLite support.This release includes a few small enhancements and a bug fix. In particular, there is now Serde support for TimeZone and the ISOWeekDate API has been
This release includes a few small enhancements and a bug fix. In particular,
there is now Serde support for TimeZone and the ISOWeekDate API has been
filled out a bit more.
Unless a serious issue is uncovered, my plan is that this will be the last
release before jiff 0.2.
Enhancements:
jiff::tz::TimeZone has been added.civil::ISOWeekDate API has been beefed up with a few convenience methods.tz::Offset::round for rounding time zone offsets.Bug fixes:
This is a small release that just removes the dev-dependency on serde_yml. It has been replaced with the deprecated serde_yaml. See this post about `s…
This is a small release that just removes the dev-dependency on serde_yml.
It has been replaced with the deprecated serde_yaml. See
this post about serde_yml shenanigans
for why this was done. Note that this was only a dev-dependency and thus doesn't
impact folks using Jiff.
Bug fixes:
serde_yml in favor of serde_yaml.This is a small release with a bug fix for precision loss in some cases when doing arithmetic on Timestamp or Zoned.
This is a small release with a bug fix for precision loss in some cases when
doing arithmetic on Timestamp or Zoned.
Bug fixes:
This is a small release with another deprecation and a new API for doing prefix parsing via strptime. There's also a bug fix for a corner case when de…
This is a small release with another deprecation and a new API for doing
prefix parsing via strptime. There's also a bug fix for a corner case
when dealing with daylight saving time gaps with the Zoned::with API.
Deprecations:
ISOWeekDate::to_date in favor of ISOWeekDate::date.Enhancements:
fmt::strtime::BrokenDownTime::parse_prefix for parsing only a prefix.Bug fixes:
Zoned::with when time falls in a DST gap.This release contains a number of deprecations in preparation for a jiff 0.2 release. The deprecations are meant to facilitate a smoother transition.…
This release contains a number of deprecations in preparation for a jiff 0.2
release. The deprecations are meant to facilitate a smoother transition. The
deprecations, when possible, come with new APIs that will permit users to write
forward compatible code that will work in both jiff 0.1 and jiff 0.2.
This release also includes a handful of new conversion specifiers in Jiff's
strftime and strptime APIs. This improves compatibility with the analogous
implementation with GNU libc.
Deprecations:
intz methods on Zoned, Timestamp, civil::DateTime and civil::Date
have been deprecated in favor of in_tz.Eq and PartialEq trait implementations on Span have been deprecated
in favor of using the new SpanFieldwise type.Span APIs has now been
deprecated. This will become an error in jiff 0.2. To continue assuming
days are 24 hours without a relative reference date, you can use the new
SpanRelativeTo::days_are_24_hours API. In jiff 0.1, you'll seen a
WARN-level log message emitted if you're code will be broken by jiff 0.2.%V and %:V have been deprecated in favor of %Q and %:Q. In
jiff 0.2, %V will correspond to the ISO 8601 week number and %:V will
result in an error. This change was made to improve compatibility with other
strtime implementations. %V and %:V continue to correspond to IANA
time zone identifiers in jiff 0.1, but using them for parsing or formatting
will result in a WARN-level deprecation message.Enhancements:
strftime and
strptime APIs. Specifically, %C, %G, %g, %j, %k, %l, %n, %R,
%s, %t, %U, %u, %W, %w. Their behavior should match the
corresponding specifiers in GNU libc.This release updates Jiff's bundled copy of the [IANA Time Zone Database] to 2025a. See the [2025a release announcement] for more details.
This release updates Jiff's bundled copy of the [IANA Time Zone Database] to
2025a. See the 2025a release announcement for more details.
Enhancements:
jiff-tzdb to 2025a.My current plan is to make a reasonably quick transition to jiff 0.2 with a few pending breaking changes. I will be making some jiff 0.1 releases with…
This release includes some bug fixes, particularly for compilation on
aarch64-linux-android. There are also some minor enhancements, such as making
Zoned::iso_week_date a convenience function for civil::Date::iso_week_date,
in line with similar functions.
My current plan is to make a reasonably quick transition to jiff 0.2 with a
few pending breaking changes. I will be making some jiff 0.1 releases with
deprecations in order to make the transition as smooth as possible. If all goes
well with jiff 0.2, then my plan is still to do a Jiff 1.0 release in the
Summer of 2025.
Deprecations:
Date::to_iso_week_date has been deprecated in favor of Date::iso_week_date.Enhancements:
Zoned::iso_week_date, DateTime::iso_week_date and
Date::iso_week_date.Bug fixes:
This release adds support for Android. This support means that Jiff will automatically read its special concatenated time zone database, and will read
This release adds support for Android. This support means that Jiff will
automatically read its special concatenated time zone database, and will
read the persist.sys.timezone property to determine the system's current
time zone.
See [PLATFORM] for more specific information about Android support.
Note that this release also removed all non-essential files (including tests and test data) for the artifact uploaded to crates.io. If you need or want these files, please open a new issue.
Enhancements:
This release includes a new API for setting the unit designator label in a friendly formatted duration for zero-length durations.
This release includes a new API for setting the unit designator label in a friendly formatted duration for zero-length durations.
Enhancements:
This release includes a new type, Pieces, in the jiff::temporal sub-module. This exposes the individual components of a parsed Temporal ISO 8601 datet
This release includes a new type, Pieces, in the jiff::fmt::temporal
sub-module. This exposes the individual components of a parsed Temporal
ISO 8601 datetime string. It allows users of Jiff to circumvent the checks
in the higher level parsing routines that prevent you from shooting yourself
in the foot.
For example, parsing into a Zoned will return an error for raw RFC 3339
timestamps like 2025-01-03T22:03-05 because there is no time zone annotation.
Without a time zone, Jiff cannot do time zone aware arithmetic and rounding.
Instead, such a datetime can only be parsed into a Timestamp. This lower
level Pieces API now permits users of Jiff to parse this string into its
component parts and assemble it into a Zoned if they so choose.
Enhancements:
fmt::temporal::Pieces for granular datetime parsing and formatting.This releases includes a UTF-8 related bug fix and a few enhancements.
This releases includes a UTF-8 related bug fix and a few enhancements.
Firstly, a Span's default Display implementation now writes uppercase
unit designator labels. That means you'll get P1Y2M3DT4H5M6S instead
of P1y2m3dT4h5m6s by default. You can restore previous behavior via
jiff::fmt::temporal::SpanPrinter::lowercase. This change was made to improve
interoperability.
Secondly, SignedDuration now supports rounding via SignedDuration::round.
Note that it only supports rounding time units (hours or smaller). In order to
round with calendar units, you'll still need to use a Span.
Enhancements:
year, day, hour and so on.SignedDuration.Span and SignedDuration now use uppercase unit designator labels in their
default ISO 8601 Display implementation.Bug fixes:
strftime format strings from ASCII-only to all of UTF-8.This release includes a few minor enhancements. Namely, the ability to iterate over time zone transitions (in the future or the past), and some improv
This release includes a few minor enhancements. Namely, the ability to iterate
over time zone transitions (in the future or the past), and some improvements
to failure modes when Timestamp and Span arithmetic fails.
Enhancements:
This release enhances Jiff's support for no_std environments by making its alloc feature optional. When alloc is disabled, only fixed offset time zone
This release enhances Jiff's support for no_std environments by making its
alloc feature optional. When alloc is disabled, only fixed offset time
zones are supported and error messages are significantly degraded. If you have
core-only use cases for Jiff, I'd love to hear about them on the issue tracker.
Enhancements:
This release includes a new jiff::friendly module for formatting and parsing durations in a more human readable format than what ISO 8601 specifies. I
This release includes a new jiff::fmt::friendly module for formatting and
parsing durations in a more human readable format than what ISO 8601 specifies.
ISO 8601 remains the "default" duration format in Jiff due to its widespread
support. Here are some examples:
40d
40 days
1y1d
1yr 1d
3d4h59m
3 days, 4 hours, 59 minutes
3d 4h 59m
2h30m
2h 30m
1mo
1w
1 week
1w4d
1 wk 4 days
1m
0.0021s
0s
0d
0 days
3 mins 34s 123ms
3 mins 34.123 secs
3 mins 34,123s
1y1mo1d1h1m1.1s
1yr 1mo 1day 1hr 1min 1.1sec
1 year, 1 month, 1 day, 1 hour, 1 minute 1.1 seconds
1 year, 1 month, 1 day, 01:01:01.1
To quickly demonstrate this new feature, here's a simple CLI program using Clap:
use clap::Parser;
use jiff::{Span, Zoned};
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
duration: Span,
}
fn main() {
let args = Args::parse();
println!("adding duration to now: {}", &Zoned::now() + args.duration);
}
And running the program:
$ cargo run -q -- '1 year, 2 months, 5 hours'
adding duration to now: 2026-02-26T18:58:22-05:00[America/New_York]
$ cargo run -q -- 'P1Y2MT5H' # ISO 8601 durations are supported too!
adding duration to now: 2026-02-26T19:00:57-05:00[America/New_York]
With Jiff, you should no longer need to pull in crates like
humantime and
humantime-serde
to accomplish a similar task.
While this new format doesn't support any kind of internationalization, the
prevalence of the humantime crate suggests there's a desire for something
like this. The "friendly" format is meant to service all the same use cases
as humantime does for durations, but in a way that doesn't let you shoot
yourself in the foot.
The new "friendly" format is now the default for the Debug implementations
of both Span and SignedDuration. It's also available via the "alternate"
Display implementations for Span and SignedDuration as well. Moreover,
the FromStr trait implementations for both Span and SignedDuration will
parse both the ISO 8601 duration and this new "friendly" format. Finally,
when serde integration is enabled, the Deserialize implementations for
SignedDuration and Span also automatically parse either ISO 8601 or the
friendly format. For serialization, ISO 8601 remains the default, but the
jiff::fmt::serde module provides easy to use helpers to switch to the
friendly format.
The jiff::fmt::friendly module documentation provides many more details,
including a complete grammar for the format.
Enhancements:
Hash implementation for Zoned and Timestamp.Bug fixes:
This release fixes a bug where Jiff would sometimes fail to parse TZif files (found, typically, in /usr/share/zoneinfo on Unix systems). This occurred
This release fixes a bug where Jiff would sometimes fail to parse TZif files
(found, typically, in /usr/share/zoneinfo on Unix systems). This occurred
when the TZif file contained a time zone transition outside the range of Jiff's
Timestamp type (which is -9999-01-01 to 9999-12-31). The bug fix works by
clamping the out-of-range transitions to Jiff's supported range.
This bug only seems to occur in some environments where their TZif files contain more extreme values than what is typically found.
Bug fixes:
This release introduces new APIs to the RFC 2822 printer that explicitly print timestamps in a format strictly compatible with [RFC 9110].
This release introduces new APIs to the RFC 2822 printer that explicitly print timestamps in a format strictly compatible with [RFC 9110].
Enhancements:
rfc2822::DateTimePrinter::timestamp_to_rfc9110_string method.This release introduces a new jiff::TimeZone::try_system API. It is like TimeZone::system, but returns an error instead of an automatic fall back to U
This release introduces a new jiff::tz::TimeZone::try_system API. It is like
TimeZone::system, but returns an error instead of an automatic fall back to
UTC when the system time zone could not be discovered.
This also includes an update to the bundled [IANA Time Zone Database] to the
2024b release in the jiff-tzdb crate. As a reminder, the bundled database
is not used or included on Unix platforms by default. See [PLATFORM] for more
details.
Enhancements:
This release introduces some new minor APIs that support formatting Timestamp values as RFC 3339 strings with a specific offset.
This release introduces some new minor APIs that support formatting
Timestamp values as RFC 3339 strings with a specific offset.
Previously, using the standard formatting routines that Jiff provides, it was
only possible to format a Timestamp using Zulu time. For example:
use jiff::Timestamp;
assert_eq!(
Timestamp::UNIX_EPOCH.to_string(),
"1970-01-01T00:00:00Z",
);
This is fine most use cases, but it can be useful on occasion to format
a Timestamp with a specific offset. While this isn't as expressive
as formatting a datetime with a time zone (e.g., with an IANA time
zone identifier), it may be useful in contexts where you just want to
"hint" at what a user's local time is. To that end, there is a new
Timestamp::display_with_offset method that makes this possible:
use jiff::{tz, Timestamp};
assert_eq!(
Timestamp::UNIX_EPOCH.display_with_offset(tz::offset(-5)).to_string(),
"1969-12-31T19:00:00-05:00",
);
A corresponding API was added to jiff::fmt::temporal::DateTimePrinter for
lower level use.
Moreover, this release also includes new convenience APIs on the Temporal and
RFC 2822 printer types for returning strings. For example, previously, if you
were using the RFC 2822 printer to format a Timestamp, you had to do this:
use jiff::{fmt::rfc2822::DateTimePrinter, Timestamp};
let mut buf = String::new();
DateTimePrinter::new().print_timestamp(&Timestamp::UNIX_EPOCH, &mut buf).unwrap();
assert_eq!(buf, "Thu, 1 Jan 1970 00:00:00 -0000");
But now you can just do this:
use jiff::{fmt::rfc2822::DateTimePrinter, Timestamp};
assert_eq!(
DateTimePrinter::new().timestamp_to_string(&Timestamp::UNIX_EPOCH).unwrap(),
"Thu, 1 Jan 1970 00:00:00 -0000",
);
Enhancements:
Timestamp to an RFC 3339 string with a specific offset.This release includes a few small enhancements that have been requested over the last several weeks. The biggest enhancement is a new jiff::serde sub-
This release includes a few small enhancements that have been requested over
the last several weeks. The biggest enhancement is a new jiff::fmt::serde
sub-module. It provides convenience routines similar to Chrono's
chrono::serde sub-module for serializing and deserializing between a
jiff::Timestamp and an integer number of seconds, milliseconds, microseconds
or nanoseconds. For example:
use jiff::Timestamp;
#[derive(serde::Serialize, serde::Deserialize)]
struct Record {
#[serde(with = "jiff::fmt::serde::timestamp::second::required")]
timestamp: Timestamp,
}
let json = r#"{"timestamp":1517644800}"#;
let got: Record = serde_json::from_str(&json).unwrap();
assert_eq!(got.timestamp, Timestamp::from_second(1517644800).unwrap());
assert_eq!(serde_json::to_string(&got).unwrap(), json);
If you need to support optional timestamps via Option<Timestamp>, then use
jiff::fmt::serde::timestamp::second::optional instead. Similarly, if you
need to support milliseconds instead of seconds, then replace second with
millisecond in the module path.
Enhancements:
BrokenDownTime::set_{offset,iana_time_zone} APIs.Timestamp::now().to_zoned() instead of
Zoned::now().with_time_zone().jiff::fmt::serde module for integration with integer timestamps.unsafe usage in libm functions (applicable only to no-std users).This release features a small bug fix where Jiff will detect an IANA time zone identifier in some cases where it wouldn't before. While Jiff would pre
This release features a small bug fix where Jiff will detect an IANA time
zone identifier in some cases where it wouldn't before. While Jiff would
previously read the symlink metadata on /etc/localtime by default to discover
the system configured time zone on Unix systems, it wouldn't do so when
TZ=/etc/localtime. There's really no reason not to, so this release of Jiff
is fixed to use symlink sniffing on file paths provided by the TZ environment
variable.
Bug fixes:
TZ=/etc/localtime, use symlink metadata to detect IANA identifier.This release introduces new options for controlling the precision of fractional seconds when printing Zoned, Timestamp, civil::DateTime or civil::Time
This release introduces new options for controlling the precision
of fractional seconds when printing Zoned, Timestamp,
civil::DateTime or civil::Time values. This is principally exposed
via jiff::fmt::temporal::DateTimePrinter::precision, but it's also
available via the standard library's formatting machinery. For example,
if zdt is a jiff::Zoned, then format!("{zdt:.6}") will format
it into a string with microsecond precision, even if its fractional
component is zero.
Enhancements:
Your coding agent can read these notes before it upgrades. Set up the MCP server →