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

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

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

Начать курс

Работа с датами и временем в Rust: от А до Я

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

1. Установка и настройка библиотеки chrono

Библиотека chrono является де-факто стандартом для работы с датами и временем в Rust. Она предоставляет полный набор инструментов: от простых объектов даты до сложных типов с учётом временных зон.

Чтобы начать работу, добавьте зависимость в файл Cargo.toml:

[dependencies]
chrono = "0.4"

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

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

2. Основные типы данных для работы с датами

В chrono существует несколько ключевых типов, которые покрывают все потребности разработчика:

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

Рассмотрим пример создания объектов каждого типа:

// Создание NaiveDate
let date = NaiveDate::from_ymd_opt(2024, 1, 15).unwrap();
println!("Дата: {}", date); // 2024-01-15

// Создание NaiveTime
let time = NaiveTime::from_hms_opt(14, 30, 0).unwrap();
println!("Время: {}", time); // 14:30:00

// Создание NaiveDateTime
let datetime = NaiveDateTime::new(date, time);
println!("Дата и время: {}", datetime); // 2024-01-15 14:30:00

// Создание DateTime с временной зоной UTC
let utc_datetime = Utc::now();
println!("Текущее время UTC: {}", utc_datetime);

// Создание DateTime с локальной временной зоной
let local_datetime = Local::now();
println!("Текущее локальное время: {}", local_datetime);

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

Одна из самых частых задач — преобразование дат в строки и обратно. chrono использует форматные строки, похожие на strftime из C.

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

Для форматирования используйте метод .format():

use chrono::Utc;

let now = Utc::now();

// Стандартный формат ISO 8601
println!("ISO 8601: {}", now.format("%Y-%m-%dT%H:%M:%S%z"));

// Русскоязычный формат
println!("Русский формат: {}", now.format("%d.%m.%Y %H:%M"));

// Только дата
println!("Только дата: {}", now.format("%A, %d %B %Y"));

// Вывод:
// ISO 8601: 2024-01-15T14:30:00+0000
// Русский формат: 15.01.2024 14:30
// Только дата: Monday, 15 January 2024

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

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

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

Для преобразования строки в дату используйте метод parse_from_str():

use chrono::NaiveDate;
use chrono::format::ParseError;

fn parse_date(date_str: &str) -> Result<NaiveDate, ParseError> {
    NaiveDate::parse_from_str(date_str, "%d.%m.%Y")
}

fn main() {
    match parse_date("15.01.2024") {
        Ok(date) => println!("Распарсена дата: {}", date),
        Err(e) => println!("Ошибка парсинга: {}", e),
    }
    
    // Парсинг ISO 8601
    let iso_date = NaiveDate::parse_from_str("2024-01-15", "%Y-%m-%d").unwrap();
    println!("ISO дата: {}", iso_date);
}

4. Арифметические операции с датами и временем

Библиотека chrono поддерживает все основные арифметические операции: сложение, вычитание, вычисление разницы.

Сложение и вычитание временных интервалов

use chrono::{Utc, Duration};

let now = Utc::now();
println!("Сейчас: {}", now);

// Добавляем 5 дней
let in_five_days = now + Duration::days(5);
println!("Через 5 дней: {}", in_five_days);

// Вычитаем 2 часа
let two_hours_ago = now - Duration::hours(2);
println!("2 часа назад: {}", two_hours_ago);

// Добавляем 30 минут
let in_half_hour = now + Duration::minutes(30);
println!("Через 30 минут: {}", in_half_hour);

// Работа с неделями
let next_week = now + Duration::weeks(1);
println!("Через неделю: {}", next_week);

Вычисление разницы между датами

use chrono::{NaiveDate, Duration};

let start = NaiveDate::from_ymd_opt(2024, 1, 1).unwrap();
let end = NaiveDate::from_ymd_opt(2024, 12, 31).unwrap();

// Разница в днях
let diff = end - start;
println                

Блоги

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