Trabajo avanzado con fechas y horas en Rust: chrono y time

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Trabajo avanzado con fechas y horas en Rust

\n\n

En el desarrollo moderno con Rust, trabajar con fechas y horas va mucho más allá de simplemente obtener el momento actual. Al crear sistemas de alta carga, aplicaciones financieras o servicios distribuidos, se requiere un manejo preciso de las zonas horarias, análisis sintáctico eficiente, serialización y cálculos temporales complejos. En este artículo, exploraremos técnicas avanzadas para trabajar con fechas y horas utilizando las crates chrono y time.

\n\n

1. Biblioteca chrono: la base del trabajo avanzado

\n\n

La crate chrono es el estándar de facto para trabajar con fechas y horas en Rust. Proporciona dos abstracciones clave: NaiveDateTime (fecha y hora sin zona horaria) y DateTime<Tz> (fecha y hora con zona horaria).

\n\n

Ejemplo: trabajo con zonas horarias

\n\n
use chrono::{DateTime, Utc, Local, FixedOffset, NaiveDateTime};\nuse chrono::format::ParseError;\n\nfn main() -> Result<(), ParseError> {\n    // Hora actual en UTC\n    let utc_now: DateTime<Utc> = Utc::now();\n    println!("UTC ahora: {}", utc_now);\n\n    // Hora local actual\n    let local_now: DateTime<Local> = Local::now();\n    println!("Hora local: {}", local_now);\n\n    // Conversión a otra zona horaria (Moscú, UTC+3)\n    let moscow_offset = FixedOffset::east_opt(3 * 3600).unwrap();\n    let moscow_time = utc_now.with_timezone(&moscow_offset);\n    println!("Hora en Moscú: {}", moscow_time);\n\n    // Análisis sintáctico de una cadena con zona horaria\n    let parsed = DateTime::parse_from_rfc3339("2024-03-15T14:30:00+05:00")?;\n    println!("Analizado con offset: {}", parsed);\n\n    Ok(())\n}
\n\n

Importante: Use Utc para almacenar en bases de datos y API, y realice la conversión a zonas horarias locales solo a nivel de presentación.

\n\n

2. Cálculos temporales complejos e intervalos

\n\n

La biblioteca chrono admite aritmética de fechas con el tipo Duration y operaciones más complejas a través del trait TimeDelta. Para trabajar con intervalos y períodos (por ejemplo, "el próximo mes"), use Months y Weeks.

\n\n

Ejemplo: cálculos con fechas

\n\n
use chrono::{NaiveDate, Duration, Months, Datelike, Weekday};\n\nfn main() {\n    let start = NaiveDate::from_ymd_opt(2024, 1, 15).unwrap();\n\n    // Sumar días\n    let plus_10_days = start + Duration::days(10);\n    println!("+10 días: {}", plus_10_days);\n\n    // Sumar meses (considera la diferente duración de los meses)\n    let plus_2_months = start.checked_add_months(Months::new(2)).unwrap();\n    println!("+2 meses: {}", plus_2_months);\n\n    // Encontrar el próximo lunes\n    let next_monday = start.iter_days()\n        .skip(1)\n        .find(|d| d.weekday() == Weekday::Mon)\n        .unwrap();\n    println!("Próximo lunes: {}", next_monday);\n\n    // Diferencia entre fechas en días\n    let end = NaiveDate::from_ymd_opt(2024, 12, 31).unwrap();\n    let days_diff = end.signed_duration_since(start).num_days();\n    println!("Días entre: {}", days_diff);\n}
\n\n

Consejo: Para cálculos financieros, use checked_add_months en lugar de una simple suma de días, para manejar correctamente los finales de mes (por ejemplo, 31 de enero + 1 mes = 28/29 de febrero).

\n\n

3. Serialización y análisis sintáctico de fechas con serde

\n\n

Al trabajar con JSON, YAML o bases de datos, la serialización correcta de fechas es crítica. La crate chrono se integra con serde a través de la feature serde. Para formatos personalizados, use los atributos #[serde(with = "...")].

\n\n

Ejemplo: serialización en ISO 8601 y formatos personalizados

\n\n
use chrono::{DateTime, Utc, NaiveDateTime};\nuse serde::{Serialize, Deserialize};\n\n#[derive(Debug, Serialize, Deserialize)]                

Blogs

Book Recommendations