Encuentre si han pasado 24 horas entre fechas y horas

Resuelto cybertextron asked hace 10 años • 2 respuestas

Tengo el siguiente método:

# last_updated is a datetime() object, representing the last time this program ran
def time_diff(last_updated):
    day_period = last_updated.replace(day=last_updated.day + 1, 
                                      hour=1,
                                      minute=0,  
                                      second=0,
                                      microsecond=0)
    delta_time = day_period - last_updated
    hours = delta_time.seconds // 3600
    # make sure a period of 24hrs have passed before shuffling
    if hours >= 24:
        print "hello"
    else:
        print "do nothing"

Quiero saber si han pasado 24 horas desde entonces last_updated, ¿cómo puedo hacerlo en Python?

cybertextron avatar Oct 11 '14 17:10 cybertextron
Aceptado

Si last_updatedes un objeto ingenuo de fecha y hora que representa la hora en UTC:

from datetime import datetime, timedelta

if (datetime.utcnow() - last_updated) > timedelta(hours=24): 
    # more than 24 hours passed

Si last_updatedes la hora local (objeto de fecha y hora ingenuo (sin reconocimiento de zona horaria):

import time

DAY = 86400
now = time.time()
then = time.mktime(last_updated.timetuple())
if (now - then) > DAY:
    # more than 24 hours passed

Si last_updatedes una hora ambigua, por ejemplo, la hora durante una transición de fin de horario de verano (una vez al año en muchas zonas horarias), entonces hay una probabilidad del cincuenta por ciento de que mktime()arroje un resultado incorrecto (por ejemplo, con una diferencia de una hora).

time.mktime()También puede fallar si timela biblioteca C no utiliza una base de datos de zona horaria histórica en una plataforma determinada y el desplazamiento UTC para la zona horaria local era diferente en last_updatedese momento comparado con el actual. Puede aplicarse a más de un tercio de todas las zonas horarias durante el último año. Linux, OS X, las versiones recientes de Windows tienen la base de datos tz (no sé si las versiones antiguas de Windows funcionarían para fechas tan pasadas).

Cuidado: puede resultar tentador escribir datetime.now() - last_updated(similar al caso de UTC), pero se garantiza que fallará en todas las plataformas si el desplazamiento de UTC fue diferente en el last_updatedmomento (es posible en muchas zonas horarias). mktime()La solución basada en tz puede utilizar la base de datos tz al menos en algunas plataformas y, por lo tanto, puede manejar los cambios en el desplazamiento UTC por cualquier motivo allí.

Para portabilidad, puede instalar la base de datos tz. Lo proporciona un pytzmódulo en Python. tzlocalpuede devolver pytzla zona horaria correspondiente a la zona horaria local:

from datetime import datetime, timedelta
from tzlocal import get_localzone # $ pip install tzlocal

tz = get_localzone() # local timezone
then = tz.normalize(tz.localize(last_updated)) # make it timezone-aware
now = datetime.now(tz) # timezone-aware current time in the local timezone
if (now - then) > timedelta(hours=24):
    # more than 24 hours passed

Funciona incluso si la compensación UTC fue diferente en el pasado. Pero no puede (ni tampoco time.mktime()) corregir tiempos ambiguos ( tz.localize()elige is_dst=Falseel tiempo de forma predeterminada). tz.normalize()se llama para ajustar tiempos no existentes, por ejemplo, aquellos que corresponden a una transición de inicio de horario de verano (no debería afectar el resultado).

El código anterior supone que last_updatedes un objeto de fecha y hora ingenuo (sin información de zona horaria asociada). Si last_updatedes un objeto de fecha y hora consciente, entonces es fácil convertirlo a UTC:

from datetime import datetime, timedelta

then_in_utc = last_updated.replace(tzinfo=None) - last_updated.utcoffset()
if (datetime.utcnow() - then_in_utc) > timedelta(hours=24):
    # more than 24 hours passed

Nota general: ahora debería comprender por qué la gente recomienda trabajar con la hora UTC y utilizar la hora local sólo para la visualización.

jfs avatar Oct 11 '2014 10:10 jfs

Solo para aclarar algunas cosas, porque no creo que todos hagamos uso de la timebiblioteca de Python. Cuando usas datetime, que es especialmente en Django una práctica muy común, si haces la comparación de esta manera:

if (now - then) > DAY:

fracasará enormemente . Esto se debe a que no se puede comparar datetime.timedeltacon int.

La solución a esto es convertir tus objetos a segundos.
Por ejemplo:

from datetime import datetime

then = datetime_object
now = datetime.now()

if (now - then).total_seconds() > NUMBER_OF_SECONDS:
    # do something

Espero haber ayudado a quienes hayan tenido problemas al respecto.
Salud

Kostas Livieratos avatar Dec 08 '2015 11:12 Kostas Livieratos