Working with Dates in Rust: Libraries for Time and Calendar
Rust is a modern systems programming language that offers strong typing and memory safety. However, the Rust standard library provides only minimal tools for working with dates and time. For full-featured work with calendars, time zones, formatting, and calculations, developers use third-party crates. In this article, we will take a detailed look at three main libraries: chrono, time, and jiff, and provide practical examples.
1. The chrono Library — The De Facto Standard
chrono is the most popular library for working with dates in Rust. It provides a rich API for creating, manipulating, and formatting dates and time. The main types are: NaiveDate, NaiveDateTime, DateTime (timezone-aware), and Duration.
Installation
# Cargo.toml[dependencies]chrono = "0.4"Example: Current Date and Time
use chrono::{Local, Utc};
fn main() { let now_utc = Utc::now(); let now_local = Local::now(); println!("UTC: {}", now_utc); println!("Local: {}", now_local);}Example: Parsing a String and Formatting
use chrono::NaiveDate;
fn main() { let date = NaiveDate::parse_from_str("2025-03-15", "%Y-%m-%d") .expect("Invalid date format"); println!("Day: {}", date.format("%d.%m.%Y"));}Pros: huge community, timezone support via chrono-tz, working with intervals and durations.
Cons: relatively large size, complexity when working with non-standard calendars.
2. The time Library — A Lightweight Alternative
time is a more modern and lightweight library that is actively developed. It uses a strict type system to prevent errors (e.g., separating Date, Time, OffsetDateTime, and PrimitiveDateTime).
Installation
[dependencies]time = "0.3"Example: Creating a Date and Calculating the Difference
use time::{Date, Month, Duration};
fn main() { let start = Date::from_calendar_date(2025, Month::March, 10).unwrap(); let end = Date::from_calendar_date(2025, Month::March, 20).unwrap(); let diff = end - start; println!("Difference: {} days", diff.whole_days());}Example: Formatting
use time::OffsetDateTime;use time::format_description::well_known::Rfc3339;
fn main() { let now = OffsetDateTime::now_utc(); let formatted = now.format(&Rfc3339).unwrap(); println!("RFC 3339: {}", formatted);}Pros: small size, clear type separation, excellent documentation.
Cons: fewer examples online compared to chrono.
3. The jiff Library — For High-Precision Intervals
jiff is a specialized library for working with calendar intervals and recurring events. It is useful for scheduling tasks, reminders, and calculating business days.
Installation
[dependencies]jiff = "0.1"Example: Creating an Interval and Checking Membership
use jiff::ZonedInterval;use jiff::tz::TimeZone;
fn main() { let tz = TimeZone::get("Europe/Moscow").unwrap(); let start = tz.to_zoned(2025, 3, 1, 0, 0, 0, 0).unwrap(); let end = tz.to_zoned(2025, 3, 31, 23, 59, 59, 0).unwrap(); let interval = ZonedInterval::new(start, end); let check = tz.to_zoned(2025, 3, 15, 12, 0, 0, 0).unwrap(); println!("Does March 15 fall within the interval? {}", interval.contains(&check));}Pros: convenient for calen