Working with Dates and Time in Rust: A Complete Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction to Working with Dates and Time in Rust



Working with dates and time is one of the key tasks in most modern applications. Whether it's event logging, calculating deadlines, processing timestamps from an API, or working with a calendar — a quality library for time handling is essential. In the Rust ecosystem, the standard library provides only basic capabilities (std::time::Instant and std::time::Duration), which are suitable for performance measurement but not for full-fledged calendar date operations.



The chrono crate comes to the rescue — the de facto standard for working with dates and time in Rust. It offers a wide range of functionality: from creating simple dates to working with time zones, formatting, and arithmetic. In this article, we will thoroughly examine the main capabilities of chrono, provide practical examples, and show how to avoid common mistakes.



1. Installation and Basic chrono Types



To begin, add the dependency to your Cargo.toml:



[dependencies]chrono = "0.4"


After that, you can import the necessary types. Chrono offers three key types for representing dates and time:



  • NaiveDate — date without time (year, month, day).
  • NaiveDateTime — date and time without time zone consideration.
  • DateTime<Tz> — date and time with time zone binding (e.g., Utc or Local).


Let's look at a simple example of creating these types:



use chrono::{NaiveDate, NaiveDateTime, DateTime, Utc, Local};

fn main() { // Create a naive date (without time) let date = NaiveDate::from_ymd_opt(2025, 10, 15).unwrap(); println!("Date: {}", date);

// Create a naive time (without date) let time = NaiveTime::from_hms_opt(14, 30, 0).unwrap(); println!("Time: {}", time);

// Combine into NaiveDateTime let naive_dt = NaiveDateTime::new(date, time); println!("Naive datetime: {}", naive_dt);

// Current time in UTC and local let now_utc: DateTime<Utc> = Utc::now(); let now_local: DateTime<Local> = Local::now(); println!("Now UTC: {}", now_utc); println!("Now local: {}", now_local);}


Note the use of from_ymd_opt and from_hms_opt — they return Option, which protects against creating invalid dates (e.g., January 32).



2. Formatting and Parsing Dates



Chrono uses a powerful formatting system based on specifiers, very similar to strftime from C/PHP. This allows flexible conversion of dates to strings and back.



2.1 Formatting a Date to a String



use chrono::{Utc, DateTime};

fn main() { let now: DateTime<Utc> = Utc::now(); // Standard ISO 8601 println!("ISO: {}", now.to_rfc3339()); // Custom format println!("Custom: {}", now.format("%Y-%m-%d %H:%M:%S")); println!("Day of week: {}", now.format("%A")); println!("Month: {}", now.format("%B")); println!("Year-month-day: {}", now.format("%d.%m.%Y"));}


Main formatting specifiers:

  • %Y — year (4 digits)
  • %m — month (01-12)
  • %d — day of month (01-31)
  • %H — hours (00-23)
  • %M — minutes (00-59)
  • %S — seconds (00-60)
  • %A — full weekday name
  • %B — full month name


2.2 Parsing a String into a Date



For reverse conversion, the parse_from_str method is used:



use chrono::{NaiveDateTime, DateTime, Utc, format::ParseResult};                

Blogs

Book Recommendations