1 puntos por GN⁺ 2025-04-14 | Aún no hay comentarios. | Compartir por WhatsApp
  • Whenever es una biblioteca de fecha y hora para Python que evita mediante tipos la mezcla de valores naive/aware y los errores de cálculo con DST en datetime, y puede usarse con implementación en Rust o en Python puro
  • La biblioteca estándar datetime no siempre refleja DST, y se muestra el ejemplo datetime(2023, 3, 25, 22, tzinfo=ZoneInfo("Europe/Paris")) + timedelta(hours=8), que devuelve 6:00 en lugar de 7:00 aunque por DST se omitió una hora
  • El sistema de tipos no puede distinguir naive y aware usando un solo datetime, pero Whenever separa tipos por caso de uso como Instant, ZonedDateTime y PlainDateTime para que el verificador de tipos pueda detectar errores
  • En la tabla comparativa, Arrow y Pendulum no cumplen al mismo tiempo con seguridad ante DST, aware/naive tipado y rendimiento, mientras que Whenever sí ofrece DST-safe, aware/naive tipado y fast
  • Aún está antes de la versión 1.0, por lo que la API puede cambiar en lanzamientos minor; los cambios se explican en el changelog y el verificador de tipos o el IDE pueden ayudar con los ajustes

El problema que Whenever busca resolver

  • Whenever es una biblioteca que ayuda a escribir código de fecha y hora correcto y verificable por tipos en Python
  • Ofrece una implementación en Rust y también una versión en Python puro para quienes no quieran usar Rust
  • Está diseñada con base en conceptos probados usados en bibliotecas modernas de fecha y hora de otros lenguajes
  • Se presenta como mucho más rápida que otras bibliotecas de terceros y, por lo general, incluso más rápida que la biblioteca estándar
  • El lanzamiento 1.0 sigue en espera para pulir mejor la API de largo plazo, especialmente mientras recibe comentarios sobre duration

Limitaciones de datetime de la biblioteca estándar

  • datetime de Python ha crecido durante más de 20 años y tiene aspectos que no coinciden con lo que hoy se espera de una biblioteca moderna de fecha y hora
  • Problema de cálculos con DST

    • datetime no siempre toma en cuenta el Daylight Saving Time (DST)
    • En el código de ejemplo, si se suman 8 horas a las 22:00 del 25 de marzo de 2023 en la zona horaria Europe/Paris, debería dar 7:00 porque por DST se saltó una hora, pero devuelve 6:00
    • No es un bug, sino una decisión de diseño para considerar DST solo en cálculos donde intervienen dos zonas horarias
  • Problema de distinción de tipos naive/aware

    • Con un solo tipo datetime, el sistema de tipos no puede distinguir entre naive datetime y aware datetime
    • Una firma como def schedule_meeting(at: datetime) -> None: ... no permite saber si espera un valor naive o aware

Comparación con Arrow y Pendulum

  • Según la tabla comparativa, Whenever cumple con DST-safe, aware/naive tipado y fast
  • datetime solo cumple con fast, pero no con DST-safe ni con aware/naive tipado
  • Arrow intenta ofrecer una API más amigable que la biblioteca estándar, pero no resuelve los problemas centrales
    • Mantiene los mismos footguns
    • La decisión de reducir todo a un solo tipo arrow.Arrow hace que al verificador de tipos le resulte más difícil detectar errores
  • Pendulum en 2016 se presentó con mejor manejo de DST y mejor rendimiento, pero solo corrige algunas trampas relacionadas con DST
    • El rendimiento se ha deteriorado mucho con el tiempo
    • Lleva una larga etapa de mantenimiento estancado, con solo 2 lanzamientos en los últimos 4 años, y todavía quedan muchos issues graves y antiguos

Funciones principales

  • Soporta DST-safe arithmetic
  • Previene bugs comunes con una API segura por tipos
  • Corrige problemas que Arrow y Pendulum no pudieron resolver
  • Está basada en conceptos probados y familiares
  • Ofrece alto rendimiento
  • Tiene buenas pruebas y documentación
  • Soporta aritmética de fechas
  • Soporta precisión de nanosegundos
  • Ofrece soporte para SQLAlchemy
  • El soporte para Pydantic está en beta
  • Ofrece implementación en Rust y una opción en Python puro
  • El soporte para free-threading está en beta
  • Soporta per-interpreter GIL

Flujo de uso de ejemplo

  • Importa tipos explícitos como Instant, ZonedDateTime y PlainDateTime para representar distintos casos de uso
  • Instant.now() identifica un momento específico sin complejidad de zona horaria ni calendario
  • Convierte la zona horaria de forma explícita, por ejemplo con now.to_tz("Europe/Paris")
  • PlainDateTime("2023-10-28 22:00") no se mezcla accidentalmente con otros tipos
    • Si se llama add(hours=6), aparece una NaiveArithmeticWarning indicando que el ajuste de hora local ignora DST
    • Es necesario asumir explícitamente una zona horaria con assume_tz("Europe/Amsterdam")
  • Si se ejecuta add(hours=6) sobre ZonedDateTime, el resultado refleja la transición de DST y devuelve 2023-10-29 03:00:00+01:00[Europe/Amsterdam]
  • Soporta comparación, redondeo y truncado, parsing de formatos ISO8601·RFC3339·RFC2822 y formateo con patrones personalizados
  • Si hace falta, puede convertirse a datetime de la biblioteca estándar o a la inversa
  • El uso detallado puede consultarse en feature overview y API reference

Restricciones y política de estabilidad

  • El rango soportado es el calendario gregoriano proléptico desde el año 1 hasta 9999
  • Los offsets de zona horaria están limitados a enteros en segundos, en consistencia con la IANA TZ DB
  • Whenever sigue semantic versioning
  • Antes de la 1.0, la API puede cambiar en lanzamientos minor
  • Los breaking changes se explican en detalle en el changelog
  • La API está completamente tipada, así que el verificador de tipos o el IDE pueden ayudar a adaptarse a cambios de API

Licencia e influencias de diseño

  • Whenever se distribuye bajo MIT License
  • El binary wheel incluye dependencias de Rust con licencias igualmente permisivas, como MIT y Apache-2.0
  • Noda Time y Joda Time fueron pioneras en el enfoque de tipos por concepto, y la jerarquía de tipos de Noda Time inspira directamente el diseño de Whenever
  • Temporal inspiró el manejo de casos complejos alrededor de la ambigüedad por DST y el redondeo
  • El módulo datetime de Python se usa ampliamente para el manejo de fecha y hora de bajo nivel en la implementación en Python puro de Whenever
  • También toma algunas ideas de Jiff
  • La gráfica comparativa de benchmarks está adaptada del proyecto Ruff

Aún no hay comentarios.

Aún no hay comentarios.