Trabalho com datas e horas em Rust: técnicas avançadas e bibliotecas

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Trabalho Avançado com Datas e Horas em Rust: de NaiveDateTime a Timezone



Trabalhar com datas e horas é uma das tarefas mais comuns no desenvolvimento backend, logging, sistemas financeiros e processamento de dados. Em Rust, a biblioteca padrão fornece o módulo básico std::time, mas para projetos sérios ele não é suficiente. Em um nível avançado, recorremos à crate chrono — o padrão de facto para trabalhar com datas e horas. Neste artigo, abordaremos cenários complexos: trabalho com fusos horários, parsing de formatos não padronizados, manipulações de durações e otimização de desempenho.



1. Instalação e estrutura básica do chrono



Adicione a dependência no Cargo.toml:



[dependencies]chrono = { version = "0.4", features = ["serde"] }


Principais tipos do chrono para trabalho avançado:

  • NaiveDateTime — data-hora sem fuso horário (local).
  • DateTime<Tz> — data-hora vinculada a um fuso horário (ex.: Utc, Local, FixedOffset).
  • Duration — intervalo de tempo (diferente de std::time::Duration, suporta valores negativos).
  • TimeDelta — sinônimo para Duration em versões mais recentes.


Exemplo de criação do momento atual em UTC e hora local:



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

fn main() { let utc_now: DateTime<Utc> = Utc::now(); let local_now: DateTime<Local> = Local::now(); println!("UTC: {}", utc_now); println!("Local: {}", local_now);}


2. Trabalho com fusos horários (Timezone)



Um dos recursos poderosos do chrono é o suporte ao banco de dados de fusos horários Olson através da crate chrono-tz. Isso permite trabalhar com nomes de zonas como "Europe/Moscow" ou "America/New_York".



Instale:



[dependencies]chrono = "0.4"chrono-tz = "0.8"


Exemplo de conversão de horário entre zonas:



use chrono::{Utc, DateTime, TimeZone};use chrono_tz::Europe::Moscow;

fn main() { let utc_time: DateTime<Utc> = Utc::now(); let moscow_time = utc_time.with_timezone(&Moscow); println!("UTC: {}", utc_time); println!("Moscow: {}", moscow_time);}


Ponto importante: sempre armazene o horário em UTC no banco de dados e converta para o horário local apenas ao exibir para o usuário. Isso evita confusão com horário de verão/inverno.



2.1. Trabalho com FixedOffset



Se você conhece um deslocamento fixo (ex.: +03:00), use FixedOffset:



use chrono::{FixedOffset, DateTime, Utc};

fn main() { let offset = FixedOffset::east_opt(3 * 3600).unwrap(); // +03:00 let now_utc: DateTime<Utc> = Utc::now(); let now_offset = now_utc.with_timezone(&offset); println!("Com offset +03:00: {}", now_offset);}


3. Parsing e formatação de datas (técnicas avançadas)



O parsing padrão via parse_from_str exige um formato exato. Mas em projetos reais, os formatos podem variar (ex.: logs de sistemas diferentes). Vamos considerar algumas abordagens.



3.1. Múltiplos formatos com try_parse



Use a iteração sobre formatos:



use chrono::NaiveDateTime;

fn parse_flexible(date_str: &str) -> Option<NaiveDateTime> { let formats = [ "%Y-%m-%d %H:%M:%S", "%d/%m/%Y %H:%M", "%Y%m%dT%H%M%S", "%b %d %Y %I:%M:%S%p", ];

for fmt in &formats { if let Ok(dt) = NaiveDateTime::parse_from_str(date_str, fmt) { return Some(dt); } } None}

fn main() { let dates = vec![ "2024-03-15 14:30:00", "15/03/2024 14:30", "2

Blogs

Book Recommendations