Comparando fechas y horas en Python con y sin zonas horarias

En este tutorial, veremos cómo comparar fechas en Python, con y sin zonas horarias, usando pytz, con ejemplos.

Introducción

Al trabajar con fechas, a menudo le gustaría saber si una fecha determinada es anterior o posterior a otra fecha. Podemos obtener estas respuestas comparando fechas.

En este artículo, aprenderemos a usar el módulo datetime de Python para crear y comparar fechas ingenuas (sin información de zona horaria) y conscientes (con información de zona horaria).

Para comparar las fechas, usaremos los operadores de comparación en Python: <, >, ==, <=, >=, !=.

Nota: El módulo datetime tiene dos métodos para crear objetos de fechas: datetime.datetime y datetime.date. Las comparaciones solo se pueden hacer en objetos creados a partir de la misma clase:

1
datetime.datetime.now() >= datetime.date.today()

Esto resultará en un TypeError:

1
TypeError: can't compare datetime.datetime to datetime.date

Comparación de fechas y horas ingenuas de zonas horarias

Comencemos con la comparación de fechas ingenuas, que no tienen información sobre la zona horaria. Primero, querremos importar el módulo datetime:

1
from datetime import datetime, date

Entonces, hagamos algunas fechas que podamos comparar:

1
2
3
4
date1 = date(1995, 3, 20)
date2 = date(2020, 1, 1)
dob_a = datetime(1995, 3, 20)
dob_b = datetime(2020, 1, 1)

Comparar estos objetos es tan fácil como comparar, por ejemplo, números enteros. Una fecha es menor que otra, si su hora precede a la otra.

En nuestro caso, fecha1 se considera menos (<) que fecha2 porque está más atrás en el tiempo:

1
2
3
print("date1 comes before date2?", date1 < date2)
print("date1 comes after date2?", date1 > date2)
print("date1 is equal to date2?", date1 == date2)

Esto resulta en:

1
2
3
date1 comes before date2? True
date1 comes after date2? False
date1 is equal to date2? False

Ahora, normalmente incorporaría esta lógica en algunas declaraciones de control de flujo:

1
2
3
4
if  dob_a > dob_b:
    print("person a is older than person b")
else:
    print("person b is older than person a")

Esto resulta en:

1
person b is older than person a

Comparación de fechas y horas con reconocimiento de zonas horarias

Las zonas horarias pueden complicar un poco las cosas, aunque, afortunadamente, podemos aplicar exactamente la misma lógica a la comparación. La única diferencia es que estamos trabajando con fechas conscientes: fechas con información adicional sobre la zona horaria en la que se encuentran:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from datetime import datetime
import pytz

# Create timezone objects for different parts of the world
tz_ny= pytz.timezone('America/New_York')
tz_lon = pytz.timezone("Europe/London")

# Year, Month, Day, Hour, Minute, Second
datetime = datetime(2010, 4, 20, 23, 30, 0)

# Localize the given date, according to the timezone objects
date_with_timezone_1 = tz_ny.localize(datetime)
date_with_timezone_2 = tz_lon.localize(datetime)

# These are now, effectively no longer the same *date* after being localized
print(date_with_timezone_1) # 2010-04-20 23:30:00-04:00
print(date_with_timezone_2) # 2010-04-20 23:30:00+01:00

print(date_with_timezone_1 == date_with_timezone_2)

Ejecutar este código da como resultado:

1
False

Mientras que esta declaración:

1
print(date_with_timezone_1 > date_with_timezone_2)

Daría como resultado:

1
True

Ahora, este resultado podría parecerte un poco extraño. Estamos comparando estas dos fechas y horas:

1
2
2010-04-20 23:30:00-04:00 # date_with_timezone_1
2010-04-20 23:30:00+01:00 # date_with_timezone_2

Intuitivamente, parece que date_with_timezone_2 es mayor que date_with_timezone_1. Sin embargo, echemos un vistazo a cómo funciona la función localize().

Aquí, hemos utilizado la biblioteca pytz para que nuestras fechas ingenuas sean conscientes. Hemos construido un objeto de zona horaria para Nueva York (tz_ny) y un objeto de zona horaria para Londres (tz_lon).

Luego, para inyectar información de la zona horaria en nuestro objeto datetime, ejecutamos la función localize() y empaquetamos el resultado en date_with_timezone_1 y date_with_timezone_2.

Ingresamos las 11:30 p. m. en localize(), que a su vez creó una fecha y hora para las 11:30 p. m. en Nueva York y las 11:30 p. m. en Londres, respectivamente. Para ir de las 23:30 en Nueva York a las 23:30 en Londres, tendrías que añadir 4 horas. Ha pasado más tiempo para llegar a Nueva York a las 11:30 p. m., que lo que se tardó en llegar a Londres a las 11:30 p. m. Por lo tanto, la fecha y hora correspondiente a Nueva York a las 23:30 es mayor que la fecha y hora correspondiente a Londres a las 23:30.

Tenga en cuenta este comportamiento cuando trabaje con zonas horarias de esta manera.

Sin embargo, vale la pena señalar que comparar fechas conscientes con fechas ingenuas dará como resultado un error:

1
2
date_with_timezone = tz_ny.localize(datetime)
print(datetime == date_without_timezone)

Esto resultará en el siguiente error:

1
TypeError: can't compare offset-naive and offset-aware datetimes

Entonces, para comparar objetos de fecha y hora, ambos objetos deben ser ingenuos o conscientes.

Conclusión

En este artículo, hemos discutido formas de comparar fechas en Python con reconocimiento de zona horaria e ingenua de zona horaria, también hemos analizado posibles dificultades que podemos encontrar al comparar fechas y posibles soluciones.

Si tiene alguna pregunta o contribución, déjela en la sección de comentarios a continuación.

Licensed under CC BY-NC-SA 4.0