Como Trabalhar com Datas em Rust

Aprenda a trabalhar com datas em Rust usando a crate chrono: NaiveDate, DateTime, formatação, parsing, duração e cálculos com datas. Código completo.

Trabalhar com datas e horários é uma necessidade comum em quase todo projeto. A biblioteca padrão do Rust oferece apenas std::time::SystemTime para o tempo do sistema e Duration para intervalos. Para operações completas com datas, a crate chrono é o padrão da comunidade Rust. Nesta receita, você vai aprender a criar, formatar, fazer parsing e calcular com datas.

Dependências

[package]
name = "receita-datas"
version = "0.1.0"
edition = "2021"

[dependencies]
chrono = "0.4"

Código Completo

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

fn main() {
    // =============================================
    // 1. Obtendo a data/hora atual
    // =============================================
    let agora_utc: DateTime<Utc> = Utc::now();
    let agora_local: DateTime<Local> = Local::now();

    println!("=== Data e Hora Atual ===");
    println!("UTC:   {}", agora_utc);
    println!("Local: {}", agora_local);

    // =============================================
    // 2. Criando datas específicas
    // =============================================
    println!("\n=== Criando Datas ===");

    // NaiveDate — data sem fuso horário
    let data = NaiveDate::from_ymd_opt(2026, 2, 23).unwrap();
    println!("Data: {}", data); // 2026-02-23

    // NaiveTime — hora sem fuso horário
    let hora = NaiveTime::from_hms_opt(14, 30, 0).unwrap();
    println!("Hora: {}", hora); // 14:30:00

    // NaiveDateTime — data + hora sem fuso horário
    let data_hora = NaiveDateTime::new(data, hora);
    println!("Data e hora: {}", data_hora); // 2026-02-23 14:30:00

    // A partir de timestamp Unix
    let timestamp = DateTime::from_timestamp(1740000000, 0).unwrap();
    println!("Timestamp 1740000000: {}", timestamp);

    // =============================================
    // 3. Acessando componentes
    // =============================================
    let agora = Local::now();
    println!("\n=== Componentes ===");
    println!("Ano:       {}", agora.year());
    println!("Mês:       {}", agora.month());
    println!("Dia:       {}", agora.day());
    println!("Hora:      {}", agora.hour());
    println!("Minuto:    {}", agora.minute());
    println!("Segundo:   {}", agora.second());
    println!("Dia da semana: {}", agora.weekday());
    println!("Dia do ano:    {}", agora.ordinal());

    // Verificar dia da semana
    let data = NaiveDate::from_ymd_opt(2026, 2, 23).unwrap();
    match data.weekday() {
        Weekday::Sat | Weekday::Sun => println!("{} é fim de semana", data),
        _ => println!("{} é dia útil", data),
    }

    // =============================================
    // 4. Formatando datas
    // =============================================
    let agora = Local::now();
    println!("\n=== Formatação ===");
    println!("Padrão ISO:    {}", agora.format("%Y-%m-%d %H:%M:%S"));
    println!("Brasileiro:    {}", agora.format("%d/%m/%Y"));
    println!("Hora:          {}", agora.format("%H:%M"));
    println!("Completo:      {}", agora.format("%A, %d de %B de %Y"));
    println!("RFC 2822:      {}", agora.to_rfc2822());
    println!("RFC 3339:      {}", agora.to_rfc3339());

    // Formatação customizada para logs
    println!("Log:           {}", agora.format("[%Y-%m-%d %H:%M:%S%.3f]"));

    // =============================================
    // 5. Parsing de strings para datas
    // =============================================
    println!("\n=== Parsing ===");

    // Parse de formato brasileiro
    let data = NaiveDate::parse_from_str("23/02/2026", "%d/%m/%Y").unwrap();
    println!("Parse BR:  {}", data);

    // Parse ISO
    let data = NaiveDate::parse_from_str("2026-02-23", "%Y-%m-%d").unwrap();
    println!("Parse ISO: {}", data);

    // Parse com hora
    let dt = NaiveDateTime::parse_from_str(
        "2026-02-23 14:30:00",
        "%Y-%m-%d %H:%M:%S"
    ).unwrap();
    println!("Parse DT:  {}", dt);

    // Parse RFC 3339
    let dt = DateTime::parse_from_rfc3339("2026-02-23T14:30:00-03:00").unwrap();
    println!("Parse RFC: {}", dt);

    // Tratando erros de parse
    match NaiveDate::parse_from_str("31/02/2026", "%d/%m/%Y") {
        Ok(d) => println!("Data: {}", d),
        Err(e) => println!("Erro de parse: {}", e),
    }

    // =============================================
    // 6. Aritmética com datas (Duration)
    // =============================================
    let hoje = NaiveDate::from_ymd_opt(2026, 2, 23).unwrap();
    println!("\n=== Aritmética ===");

    let amanha = hoje + Duration::days(1);
    let semana_que_vem = hoje + Duration::weeks(1);
    let mes_passado = hoje - Duration::days(30);

    println!("Hoje:            {}", hoje);
    println!("Amanhã:          {}", amanha);
    println!("Semana que vem:  {}", semana_que_vem);
    println!("30 dias atrás:   {}", mes_passado);

    // Diferença entre datas
    let natal = NaiveDate::from_ymd_opt(2026, 12, 25).unwrap();
    let dias_ate_natal = natal.signed_duration_since(hoje).num_days();
    println!("Dias até o Natal: {}", dias_ate_natal);

    // Verificar se uma data é futura ou passada
    let agora = Utc::now().date_naive();
    if natal > agora {
        println!("Natal 2026 ainda não chegou!");
    }

    // =============================================
    // 7. Exemplo prático: calcular idade
    // =============================================
    println!("\n=== Calcular Idade ===");

    fn calcular_idade(nascimento: NaiveDate) -> u32 {
        let hoje = Local::now().date_naive();
        let mut idade = (hoje.year() - nascimento.year()) as u32;

        // Ajustar se ainda não fez aniversário este ano
        if (hoje.month(), hoje.day()) < (nascimento.month(), nascimento.day()) {
            idade -= 1;
        }
        idade
    }

    let nascimento = NaiveDate::from_ymd_opt(1990, 6, 15).unwrap();
    println!(
        "Nascido em {}: {} anos",
        nascimento.format("%d/%m/%Y"),
        calcular_idade(nascimento)
    );

    // =============================================
    // 8. Listar dias do mês
    // =============================================
    println!("\n=== Dias do Mês (Fev 2026) ===");
    let mut dia = NaiveDate::from_ymd_opt(2026, 2, 1).unwrap();
    while dia.month() == 2 {
        let tipo = match dia.weekday() {
            Weekday::Sat | Weekday::Sun => "fim de semana",
            _ => "dia útil",
        };
        println!("  {} ({}) - {}", dia.format("%d/%m"), dia.weekday(), tipo);
        dia += Duration::days(1);
    }
}

Saída do Programa

=== Data e Hora Atual ===
UTC:   2026-02-23 14:30:00.123456 UTC
Local: 2026-02-23 11:30:00.123456 -03:00

=== Criando Datas ===
Data: 2026-02-23
Hora: 14:30:00
Data e hora: 2026-02-23 14:30:00
Timestamp 1740000000: 2025-02-19 20:00:00 UTC

=== Componentes ===
Ano:       2026
Mês:       2
Dia:       23
Hora:      11
Minuto:    30
Segundo:   0
Dia da semana: Mon
Dia do ano:    54
2026-02-23 é dia útil

=== Formatação ===
Padrão ISO:    2026-02-23 11:30:00
Brasileiro:    23/02/2026
Hora:          11:30
Completo:      Monday, 23 de February de 2026
RFC 2822:      Mon, 23 Feb 2026 11:30:00 -0300
RFC 3339:      2026-02-23T11:30:00-03:00
Log:           [2026-02-23 11:30:00.123]

=== Parsing ===
Parse BR:  2026-02-23
Parse ISO: 2026-02-23
Parse DT:  2026-02-23 14:30:00
Parse RFC: 2026-02-23 14:30:00 -03:00
Erro de parse: input is out of range

=== Aritmética ===
Hoje:            2026-02-23
Amanhã:          2026-02-24
Semana que vem:  2026-03-02
30 dias atrás:   2026-01-24
Dias até o Natal: 305
Natal 2026 ainda não chegou!

=== Calcular Idade ===
Nascido em 15/06/1990: 35 anos

=== Dias do Mês (Fev 2026) ===
  01/02 (Sun) - fim de semana
  02/02 (Mon) - dia útil
  ...
  28/02 (Sat) - fim de semana

Formatos Comuns de Data

CódigoSignificadoExemplo
%YAno com 4 dígitos2026
%mMês com zero02
%dDia com zero23
%HHora (24h)14
%MMinuto30
%SSegundo00
%ANome do dia da semanaMonday
%BNome do mêsFebruary
%d/%m/%YFormato brasileiro23/02/2026

Veja Também