Работа с датами и временем в Rust: полное руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в работу с датами и временем в Rust

Работа с датами и временем — одна из ключевых задач в любом современном приложении. Будь то логирование событий, планирование задач, обработка пользовательских данных или работа с API — без корректного управления временными метками не обойтись. В языке Rust, известном своей производительностью и безопасностью, стандартная библиотека предоставляет лишь минимальный набор инструментов для работы со временем. Однако на помощь приходит мощный крейт chrono, который стал де-факто стандартом для работы с датами и временем в экосистеме Rust.

В этой статье мы подробно разберем, как устанавливать и использовать chrono, как создавать, форматировать, парсить и манипулировать датами, а также как работать с часовыми поясами и временными метками Unix.

Установка и подключение крейта chrono

Для начала работы необходимо добавить зависимость chrono в файл Cargo.toml вашего проекта:

[dependencies]
chrono = "0.4"

После этого можно импортировать необходимые типы и трейты в коде:

use chrono::{DateTime, Utc, Local, NaiveDate, NaiveDateTime, Duration, Datelike, Timelike, TimeZone};

Крейт chrono предлагает несколько ключевых типов для представления дат и времени:

  • NaiveDate — дата без времени и часового пояса (например, 2024-01-15).
  • NaiveTime — время без даты и часового пояса (например, 14:30:00).
  • NaiveDateTime — комбинация даты и времени без учета часового пояса.
  • DateTime<Utc> — дата и время с часовым поясом UTC.
  • DateTime<Local> — дата и время с локальным часовым поясом системы.
  • DateTime<FixedOffset> — дата и время с произвольным смещением от UTC.

Создание и получение текущего времени

Самый простой способ получить текущий момент времени — использовать функции Utc::now() и Local::now():

use chrono::{Utc, Local};

fn main() {
    let utc_now: DateTime<Utc> = Utc::now();
    let local_now: DateTime<Local> = Local::now();
    
    println!("Текущее время UTC: {}", utc_now);
    println!("Текущее локальное время: {}", local_now);
}

Для создания конкретной даты можно использовать методы NaiveDate::from_ymd и NaiveDateTime::new:

use chrono::{NaiveDate, NaiveDateTime, NaiveTime};

fn main() {
    // Создание даты 15 марта 2024 года
    let date = NaiveDate::from_ymd(2024, 3, 15);
    println!("Дата: {}", date);
    
    // Создание времени 10:30:00
    let time = NaiveTime::from_hms(10, 30, 0);
    println!("Время: {}", time);
    
    // Комбинация даты и времени
    let datetime = NaiveDateTime::new(date, time);
    println!("Дата и время: {}", datetime);
}

Также можно создать дату с часовым поясом, используя метод and_hms у даты:

use chrono::{Utc, TimeZone};

fn main() {
    let datetime_utc = Utc.ymd(2024, 12, 25).and_hms(12, 0, 0);
    println!("Рождество UTC: {}", datetime_utc);
}

Форматирование и парсинг дат

Форматирование вывода

Для преобразования даты в строку используется метод format, который принимает строку формата. Спецификаторы формата аналогичны таковым в языке Python и других языках:

use chrono::{Utc, DateTime};

fn main() {
    let now = Utc::now();
    
    // Базовое форматирование
    println!("По умолчанию: {}", now.format("%Y-%m-%d %H:%M:%S"));
    println!("Только дата: {}", now.format("%d.%m.%Y"));
    println!("С названием месяца: {}", now.format("%d %B %Y года"));
    println!("Время с секундами: {}", now.format("%H:%M:%S"));
    println!("Unix timestamp: {}", now.timestamp());
}

Основные спецификаторы форматирования:

  • %Y — год (4 цифры)
  • %m — месяц (01-12)
  • %d — день месяца (01-31)
  • %H — часы (00-23)
  • %M — минуты (00-59)
  • %S — секунды (00-59)
  • %B — полное название месяца (Январь, Февраль и т.д.)
  • %A — полное название дня недели

Парсинг строк в даты

Для обратного преобразования строки в дату используется метод parse_from_str или функция NaiveDateTime::parse_from_str:

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

fn main() -> Result<(), ParseError> {
    // Парсинг строки без часового пояса
    let date_str = "2024-06-15 14:30:00";
    let naive_dt = NaiveDateTime::parse_from_str(date_str, "%Y-%m-%d %H:%M:%S")?;
    println!("Распарсено: {}", naive_dt);
    
    // Парсинг строки с часовым поясом
    let date_str_tz = "2024-06-15T14:30:00+03:00";
    let dt_with_tz = DateTime::parse_from_str(date_str_tz, "%Y-%m-%dT%H:%M:%S%z")?;
    println!("С часовым поясом: {}", dt_with_tz);
    
    // Парсинг ISO 8601 формата
    let iso_str = "2024-06-15T11:30:00Z";
    let iso_dt: DateTime<Utc> = iso_str.parse()?;
    println!("ISO 8601: {}", iso_dt);
    
    Ok(())
}

Операции с датами: сложение, вычитание и сравнение

Крейт chrono позволяет выполнять арифметические операции с датами с помощью типа Duration

Блоги

Рекомендаций по книгам