Chrono: Biblioteca de Data e Hora para Rust

Chrono tem como objetivo fornecer toda a funcionalidade necessária para realizar operações corretas com datas e horas no calendário gregoriano proléptico:

  • O tipo DateTime possui reconhecimento de fuso horário por padrão, com tipos independentes sem fuso horário.
  • Operações que podem produzir uma data e hora inválidas ou ambíguas retornam Option ou MappedLocalTime.
  • Análise e formatação configuráveis com uma sintaxe inspirada no strftime.
  • O fuso horário Local funciona com o fuso horário local atual do sistema operacional.
  • Tipos e operações são implementados para serem razoavelmente eficientes.
  • Para evitar aumentar o tamanho do binário, o Chrono não inclui dados de fuso horário por padrão. Use as crates complementares Chrono-TZ ou tzfile para suporte completo a fusos horários.

Funcionalidades

Chrono suporta vários ambientes de execução e sistemas operacionais, com diversas funcionalidades que podem ser ativadas ou desativadas.

Funcionalidades Padrão:

  • alloc: Ativa funcionalidades que dependem de alocação (principalmente formatação de strings).
  • std: Ativa funcionalidades que dependem da biblioteca padrão. É um superconjunto de alloc, adicionando interoperabilidade com tipos e traits da biblioteca padrão.
  • clock: Permite a leitura do fuso horário local (Local). É um superconjunto de now.
  • now: Permite a leitura da hora do sistema (now).
  • wasmbind: Fornece uma interface para a API Date do JS para o target wasm32.

Funcionalidades Opcionais:

  • serde: Permite serialização/desserialização via serde.
  • rkyv: Obsoleto, use as funcionalidades rkyv-*.
  • rkyv-16, rkyv-32, rkyv-64: Permitem serialização/desserialização via rkyv, usando inteiros de 16, 32 ou 64 bits respectivamente.
  • rkyv-validation: Permite suporte à validação rkyv usando bytecheck.
  • arbitrary: Constrói instâncias arbitrárias de tipos com a crate Arbitrary.
  • unstable-locales: Ativa a localização. Adiciona vários métodos com o sufixo _localized.

Visão Geral

Diferença de Tempo/Duração

Chrono fornece o tipo TimeDelta para representar a magnitude de um intervalo de tempo. Esta é uma duração "exata" representada em segundos e nanossegundos, e não representa componentes "nominais" como dias ou meses.

O tipo TimeDelta anteriormente era chamado Duration (ainda disponível como um alias de tipo). Uma diferença notável em relação ao core::time::Duration similar é que ele é um valor com sinal em vez de sem sinal.

Data e Hora

Chrono fornece o tipo DateTime para representar uma data e hora em um fuso horário.

DateTime possui reconhecimento de fuso horário e deve ser construído a partir de um objeto TimeZone, que define como a data local é convertida de e para UTC. Existem três implementações conhecidas de TimeZone:

  • Utc especifica o fuso horário UTC. É o mais eficiente.
  • Local especifica o fuso horário local do sistema.
  • FixedOffset especifica um fuso horário de deslocamento fixo arbitrário, como UTC+09:00 ou UTC-10:30.

Valores DateTime com diferentes tipos de TimeZone são distintos e não podem ser misturados, mas podem ser convertidos entre si usando o método DateTime::with_timezone.

Você pode obter a data e hora atuais no fuso horário UTC (Utc::now()) ou no fuso horário local (Local::now()).

use chrono::prelude::*;

let utc: DateTime<Utc> = Utc::now(); // ex., `2014-11-28T12:45:59.324310806Z`
let local: DateTime<Local> = Local::now(); // ex., `2014-11-28T21:45:59.324310806+09:00`

Além disso, você pode criar sua própria data e hora:

use chrono::offset::MappedLocalTime;
use chrono::prelude::*;

let dt = Utc.with_ymd_and_hms(2014, 7, 8, 9, 10, 11).unwrap(); // `2014-07-08T09:10:11Z`

Formatação e Análise

A formatação é feita através do método format, cujo formato é equivalente ao conhecido formato strftime.

O método padrão to_string e o especificador {:?} também fornecem uma representação razoável. Chrono também fornece os métodos to_rfc2822 e to_rfc3339 para formatos comuns.

Chrono agora também fornece formatação de data em quase qualquer idioma sem bibliotecas C adicionais. Esta funcionalidade está disponível sob a feature unstable-locales:

use chrono::prelude::*;

let dt = Utc.with_ymd_and_hms(2014, 11, 28, 12, 0, 9).unwrap();
assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2014-11-28 12:00:09");
assert_eq!(dt.format_localized("%A %e %B %Y, %T", Locale::fr_BE).to_string(), 
           "vendredi 28 novembre 2014, 12:00:09");

A análise pode ser feita de duas maneiras:

  1. A trait padrão FromStr (e o método parse em strings) pode ser usado para analisar valores DateTime<FixedOffset>, DateTime<Utc> e DateTime<Local>.
  2. DateTime::parse_from_str analisa uma data e hora com um deslocamento e retorna DateTime<FixedOffset>.
use chrono::prelude::*;

let dt = "2014-11-28T12:00:09Z".parse::<DateTime<Utc>>().unwrap();
let fixed_dt = DateTime::parse_from_str("2014-11-28 21:00:09 +09:00", "%Y-%m-%d %H:%M:%S %z").unwrap();

Conversão de/para Timestamps de Época

Construa DateTime<Utc> a partir de um timestamp UNIX usando DateTime::from_timestamp(seconds, nanoseconds).

Obtenha o timestamp (em segundos) de um DateTime usando DateTime.timestamp. Além disso, você pode obter o número adicional de nanossegundos com DateTime.timestamp_subsec_nanos.

use chrono::{DateTime, Utc};

// Construir datetime a partir da época:
let dt: DateTime<Utc> = DateTime::from_timestamp(1_500_000_000, 0).unwrap();
assert_eq!(dt.to_rfc2822(), "Fri, 14 Jul 2017 02:40:00 +0000");

// Obter valor de época a partir do datetime:
let dt = DateTime::parse_from_rfc2822("Fri, 14 Jul 2017 02:40:00 +0000").unwrap();
assert_eq!(dt.timestamp(), 1_500_000_000);

Limitações

  • Apenas o calendário gregoriano proléptico é suportado (ou seja, estendido para suportar datas anteriores à era).
  • Os tipos de data são limitados a aproximadamente +/- 262.000 anos da era comum.
  • Os tipos de hora são limitados à precisão de nanossegundos.
  • Segundos bissextos podem ser representados, mas o Chrono não os suporta completamente.