Library / SDK
BurntSushi/jiff avatar
BurntSushi/jiff

BurntSushi/jiff: a Rust datetime library that trades 1.0 stability for a safer API

A datetime library for Rust that encourages you to jump into the pit of success.

2,939 stars125 forksRustUnlicense

At a glance

What is it?
Jiff is a Rust datetime crate built around Temporal-style primitives, DST-aware arithmetic and IANA time zone data. It is still at 0.2.0, and its own README says there is no timeline for 1.0.
Who is it for?
Adopt jiff if you want a Rust datetime API that makes DST and time zone mistakes harder to write, and you can accept that the crate is at 0.2.0 with no announced 1.0 date. Do not adopt it if you need a frozen public API today or you build for a platform whose time zone handling is not documented in PLATFORM.md.
Can I use it commercially?
Yes. Unlicense is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 18 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What jiff solves, and who it is written for

Rust already has datetime crates, so jiff's pitch is not coverage. It is the shape of the API. The README describes the library as encouraging you to "jump into the pit of success", and the stated focus is high level datetime primitives that are difficult to misuse, with reasonable performance as a secondary goal. The design is explicitly inspired by Temporal, the TC39 proposal for JavaScript.

The intended reader is a Rust developer who has been bitten by time zone handling. The README's opening example parses an RFC 3339 instant, converts it into a zone aware datetime, adds a span and prints the result. The interesting part is the assertion: adding one month and two hours to 2024-07-11T01:14:00Z in America/New_York yields 2024-08-10T23:14:00-04:00[America/New_York]. The offset is preserved in the output, so the value round-trips rather than collapsing to UTC.

That bracket notation is the whole argument in miniature. A datetime without its zone is an incomplete value, and jiff's types are arranged so the zone travels with the instant.

Zoned, Timestamp and the data flow behind DST-aware arithmetic

The types visible in the README are Timestamp, Zoned, Span and Unit. Timestamp is an instant; Zoned is an instant plus a time zone; Span is a length of time expressed in calendar units such as months and hours, produced by the ToSpan trait. Arithmetic goes through checked_add, which returns a Result rather than panicking on an invalid result.

Time zone transitions come from the IANA Time Zone Database. On Unix, the README states that jiff usually reads /usr/share/zoneinfo and respects the TZDIR environment variable. On Windows, a copy of the time zone database is embedded into the compiled library. The system's default zone is discovered differently per platform: /etc/localtime on Unix, and on Windows a call to GetDynamicTimeZoneInformation whose Windows identifier is mapped to an IANA identifier using Unicode's CLDR XML data.

That split explains the crate features. The README points to a crate features section covering std support, serde support, and whether to embed a copy of the time zone database in your binary. Embedding is what makes Windows work without a system tzdb; it is also the choice that costs binary size. The workspace layout reflects this: crates/jiff, crates/jiff-core, crates/jiff-tzdb, crates/jiff-tzdb-platform, crates/jiff-static and crates/jiff-cli are separate members, so the database and the static build are separable from the main crate.

Formatting has its own escape hatch. The README notes that Display on Zoned makes it awkward to write into a reusable buffer, and points to jiff::fmt::temporal::DateTimePrinter::print_zoned for writing a Zoned into an existing String or Vec<u8>. The jiff::fmt submodules are described as the route for more control when the high level API is too restrictive.

Installing jiff and running a first zone aware program

The README gives a complete walkthrough. Create a project, add the dependency, replace src/main.rs, and run it. The dependency line comes from crates.io, and the README says you can either add jiff to Cargo.toml yourself or run the cargo add command below.

bash
cargo new jiff-example
cd jiff-example
cargo add jiff

The README's example program rounds the current zone aware time to the second and prints it. Note the return type: main returns Result<(), jiff::Error>, because rounding can fail.

rust
use jiff::{Unit, Zoned};

fn main() -> Result<(), jiff::Error> {
    let now = Zoned::now().round(Unit::Second)?;
    println!("{now}");
    Ok(())
}

Running it produces a zone aware string in the README's own example output, of the form 2024-07-10T19:54:20-04:00[America/New_York]. The first run compiles dependencies; later runs skip that step. What you see depends on your system time zone, which is exactly the platform lookup described above.

The README's other example is the one worth copying into a test, because it asserts both the zoned form and the UTC form of the same value.

rust
use jiff::{Timestamp, ToSpan};

fn main() -> Result<(), jiff::Error> {
    let time: Timestamp = "2024-07-11T01:14:00Z".parse()?;
    let zoned = time.in_tz("America/New_York")?.checked_add(1.month().hours(2))?;
    assert_eq!(zoned.to_string(), "2024-08-10T23:14:00-04:00[America/New_York]");
    assert_eq!(zoned.timestamp().to_string(), "2024-08-11T03:14:00Z");
    Ok(())
}

The repository also ships integration examples for database layers: examples/ contains diesel-mysql, diesel-postgres, diesel-sqlite, sqlx-postgres, sqlx-sqlite and an uptime example. If you are wiring jiff into a database, those directories are the starting point rather than the README.

The 0.2.0 problem: what the version number costs you

This is the constraint that matters more than any API detail. The current release is 0.2.0, published on 2025-02-11. The README's future plans section says the original goal was a 1.0 release in Summer 2025, that this deadline has slipped, and that there is currently no timeline for 1.0. The stated reason is that the author wants 1.0 to be as right as possible, because after release the API is intended to be committed to indefinitely.

The transition plan is spelled out: once 1.0 ships, jiff 0.2 will receive critical bug fix updates for one year, with no active feature development. Until then, anyone building on jiff is building on a pre-1.0 API. The README does not document a deprecation policy for 0.2 beyond that one-year grace period, and it does not commit to API stability before 1.0.

For a library used inside an application, that is a normal cost. For a library exposed in your own public API, it is a real risk: a 0.x minor bump can change types, and your downstream users inherit the churn. The README acknowledges the tension directly by saying users should feel comfortable using jiff as a stable base in public APIs once 1.0 is out, which is a statement about a future release, not the current one.

Performance deserves the same honesty. The README says the most important design goal is a high level API that is hard to misuse, that performance is second, and that some aspects have received optimization attention while many have not. The bench directory holds benchmarks. There is no published number to point at here, and the README does not claim one.

Where jiff is the wrong tool, and what chrono does differently

jiff is the wrong choice when you need a frozen API surface today, or when your target platform is not covered. The README says it expects support for other platforms to grow over time, and that the author will likely rely on contributor pull requests for more obscure platforms that are not easy to test. PLATFORM.md is the file to read before committing to a target; the README itself only describes Unix and Windows behavior.

It is also the wrong tool if you want a minimal dependency. Embedding the time zone database into the binary is what makes Windows work, and the crate features exist precisely because that embedding is optional. A program that only handles UTC instants does not need any of this.

The obvious alternative is chrono, which the repository compares against directly in COMPARE.md, alongside time, hifitime and icu. The difference in approach is the starting point: chrono grew around a DateTime type that carries an offset, and its time zone handling has historically leaned on the chrono-tz companion crate for IANA data. jiff starts from the Temporal model, where a zone aware value carries the IANA identifier itself and prints it in the bracketed suffix form, and where the tzdb is part of the crate's feature set rather than a separate ecosystem crate. The README's own framing is that jiff's priority order is API comprehension and correctness first, performance second, which is a different ordering than a library optimizing for minimal types.

For the full argument, COMPARE.md and DESIGN.md are the two documents to read. The README only points at them.

Licence, maintenance and the cost of upgrading

The crate is dual-licensed under MIT or the UNLICENSE, and the repository carries both LICENSE-MIT and UNLICENSE files. The Unlicense is a public domain dedication, which is a permissive option some corporate licence scanners treat differently from MIT. Which of the two applies to your use is your call; this is not legal advice, and the COPYING file is the place to look.

Maintenance is active in the narrow sense that the last push to the default branch was on 2026-09-12, and the repository is not archived. That tells you commits are landing. It does not tell you when 1.0 arrives, because the README explicitly says there is no timeline.

The upgrade cost is concentrated in one event: the 0.2 to 1.0 transition. The README commits to critical bug fixes on 0.2 for one year after 1.0 ships, which means a migration window exists but is bounded. If your code touches the formatting layer, expect that work to be the fiddly part, since jiff::fmt submodules are the escape hatch and the README positions them as the more complicated surface. Pinning to a specific 0.2.x version rather than a caret range is the mechanical way to avoid surprise minor bumps, and the CHANGELOG is where the actual breakage would be recorded.

Editorial conclusion

Adopt jiff if you want a Rust datetime API that makes DST and time zone mistakes harder to write, and you can accept that the crate is at 0.2.0 with no announced 1.0 date. Do not adopt it if you need a frozen public API today or you build for a platform whose time zone handling is not documented in PLATFORM.md. Before you start, read DESIGN.md and COMPARE.md, then run the README's cargo new jiff-example / cargo add jiff / cargo run sequence to see what Zoned::now() prints on your own machine, because that output is where the system time zone lookup actually happens.

Frequently asked questions

How does jiff differ from chrono for Rust datetime handling?

jiff is built around the Temporal model, where a zone aware value carries its IANA identifier and prints it in a bracketed suffix, and where IANA time zone data is part of the crate's feature set. chrono is compared directly in the repository's COMPARE.md, which is the document to read for the full argument.

Is jiff stable enough to use in production, given it is still 0.2.0?

The current release is 0.2.0, and the README states there is currently no timeline for a 1.0 release, with the author wanting 1.0 to be as right as possible before committing to the API indefinitely. Once 1.0 ships, jiff 0.2 is planned to get critical bug fix updates for one year, with no active feature development.

How do I install jiff in a Rust project?

Add jiff to your dependencies in Cargo.toml, or run cargo add jiff. The README walks through creating a project with cargo new, adding the dependency, and running it with cargo run.

Where does jiff get its time zone data on Unix and Windows?

On Unix, the README says jiff usually finds the IANA Time Zone Database at /usr/share/zoneinfo and respects the TZDIR environment variable. On Windows, jiff automatically embeds a copy of the time zone database into the compiled library.

Official sources

  1. BurntSushi/jiff on GitHub
  2. Issues
  3. License: Unlicense
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/burntsushi-jiff.svg)](https://hysenlabs.com/projects/burntsushi-jiff)