Comparación de fecha y hora con Delorean en Python: con y sin zonas horarias

En esta guía, hemos echado un vistazo a cómo comparar fechas en Python con Delorean, tanto para objetos de fecha y hora conscientes de la zona horaria como para objetos de fecha y hora ingenuos de la zona horaria.

Introducción

Trabajar con datetime puede ser un desafío, y manejar datetime en Python no es una excepción. El módulo datetime incorporado de Python nos presentó varias clases: date, datetime, time, timezone y timedelta, y se han generado varias bibliotecas externas para abordar los problemas presentes en el módulo oficial, como Flecha.

En esta guía, veremos cómo comparar objetos de fecha y hora en Delorean, una biblioteca basada en *pytz * que es la biblioteca estándar para resolver problemas relacionados con las zonas horarias, y dateutil que se utiliza para calcular deltas entre 2 objetos de fecha y hora determinados.

Instalación de Delorean Configuración de un entorno virtual

Delorean está disponible para su instalación a través de pip. En general, es recomendable trabajar en un entorno virtual porque te permite organizar las dependencias que requieren los diferentes proyectos de forma aislada.

En Linux o MacOS para crear un entorno virtual, ejecutaríamos:

1
2
3
$ python3 -m venv env
$ source env/bin/activate
$ python3 -m pip install delorean

Alternativamente, en Windows podemos ejecutar:

1
2
3
$ virtualenv env
$ .\env\Scripts\activate
$ python3 -m pip install delorean

Comparación de fecha y hora sin zona horaria (fecha y hora ingenua) usando Delorean

Empecemos por comparar las fechas ingenuas de la zona horaria: fechas que no llevan información de la zona horaria, pero representan un punto dado en el tiempo. Dicho esto, puede configurar la zona horaria de un objeto Delorean pero, cuando se vuelva a imprimir, estará en UTC:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from delorean import Delorean
import datetime

naive_d1 = Delorean(datetime=datetime.datetime(2021, 5, 15), timezone='UTC').naive
naive_d2 = Delorean(datetime=datetime.datetime(2021, 5, 15, 5), timezone='UTC').naive
naive_d3 = Delorean(datetime=datetime.datetime(2021, 5, 15, 5), timezone='US/Central').naive

print("naive_d1 == naive_d2 is", naive_d1 == naive_d2)
print("naive_d2 > naive_d1 is", naive_d2 > naive_d1)
print("naive_d3 == naive_d2 + 5h is", naive_d3 == naive_d2 + datetime.timedelta(hours=5))

Esto resulta en:

1
2
3
naive_d1 == naive_d2 is False
naive_d2 > naive_d1 is True
naive_d3 == naive_d2 + 5h is True

naive_d1 no es igual a naive_d2 porque tiene más información: las horas están definidas y, por lo tanto, no son las predeterminadas (mediodía).

Esto hace que naive_d2 "mayor" que naive_d1, ya que se encuentra en un momento posterior.

naive_d3 está en una zona horaria diferente que naive_d2, pero esto se rectifica fácilmente simplemente agregando un timedelta de 5 horas a naive_d2 para que coincidan, y se devuelve True para su igualdad.

Si tuviera que imprimir naive_d2 y naive_d3, aunque ambos estuvieran configurados a las 5 a.m.:

1
2
print(naive_d2)
print(naive_d3)

Obtendría un resultado cambiado, ya que ambos coinciden con UTC:

1
2
2021-05-15 05:00:00
2021-05-15 10:00:00

Comparación de fecha y hora con zona horaria (consciente de fecha y hora) mediante Delorean

Las fechas conscientes de la zona horaria no coinciden con una sola zona horaria. Si tuviera que hacer dos fechas, denotando la misma hora del reloj en dos zonas horarias diferentes:

1
2
d1 = Delorean(datetime=datetime.datetime(2021, 5, 15, 5), timezone='UTC')
d2 = Delorean(datetime=datetime.datetime(2021, 5, 15, 5), timezone='Africa/Lagos')

Si tuviera que imprimirlos, ambos indicarían las 5 a.m., pero en diferentes zonas horarias:

1
2
print(d2)
print(d3)

Esto resulta en:

1
2
Delorean(datetime=datetime.datetime(2021, 5, 15, 5, 0), timezone='UTC')
Delorean(datetime=datetime.datetime(2021, 5, 15, 5, 0), timezone='Africa/Lagos')

Esto hace que la comparación sea un poco diferente a las fechas ingenuas: ¿d2 es igual a d3 aquí? Ambos indican la misma hora del reloj, pero no el mismo punto en el tiempo. Delorean comparará si dos objetos Delorean denotan el mismo punto en el tiempo, por lo que no son lo mismo a los ojos de la biblioteca.

Sin embargo, puede agregar tiempo a las fechas con zona horaria para que coincidan. La zona horaria África/Lagos está solo una hora por detrás de UTC, por lo que si le agregamos una hora, denotarán el mismo punto en el tiempo:

1
2
3
4
5
6
7
8
9
from delorean import Delorean
import datetime

d1 = Delorean(datetime=datetime.datetime(2021, 5, 15), timezone='UTC')
d2 = Delorean(datetime=datetime.datetime(2021, 5, 15, 5), timezone='UTC')
d3 = Delorean(datetime=datetime.datetime(2021, 5, 15, 5), timezone='Africa/Lagos')

print("d2 == d3 +1h is", d2 == d3 + datetime.timedelta(hours=1))
print("d1 > d3 -", d1 > d3)

Además, dado que d1 no tiene datos sobre las horas, está configurado para el mediodía. Aunque d1 pertenece a UTC, todavía faltan 4 horas antes de d3:

1
2
d2 == d3 +1h is True
d1 > d3 - False

Conclusión

En esta guía, hemos analizado cómo comparar fechas ingenuas y conscientes de la zona horaria en Delorean.