¿La forma más limpia y pitónica de conseguir la cita de mañana?

120

¿Cuál es la forma más limpia y pitónica de conseguir la cita de mañana? Debe haber una mejor manera que agregar uno al día, manejar los días al final del mes, etc.

linkmaster03
fuente

Respuestas:

241

datetime.date.today() + datetime.timedelta(days=1) debería hacer el truco

Kamil Szot
fuente
39

timedelta puede manejar la adición de días, segundos, microsegundos, milisegundos, minutos, horas o semanas.

>>> import datetime
>>> today = datetime.date.today()
>>> today
datetime.date(2009, 10, 1)
>>> today + datetime.timedelta(days=1)
datetime.date(2009, 10, 2)
>>> datetime.date(2009,10,31) + datetime.timedelta(hours=24)
datetime.date(2009, 11, 1)

Como se preguntó en un comentario, los días bisiestos no representan ningún problema:

>>> datetime.date(2004, 2, 28) + datetime.timedelta(days=1)
datetime.date(2004, 2, 29)
>>> datetime.date(2004, 2, 28) + datetime.timedelta(days=2)
datetime.date(2004, 3, 1)
>>> datetime.date(2005, 2, 28) + datetime.timedelta(days=1)
datetime.date(2005, 3, 1)
Mark Rushakoff
fuente
7

Sin manejo de segundos intercalares aunque:

>>> from datetime import datetime, timedelta
>>> dt = datetime(2008,12,31,23,59,59)
>>> str(dt)
'2008-12-31 23:59:59'
>>> # leap second was added at the end of 2008, 
>>> # adding one second should create a datetime
>>> # of '2008-12-31 23:59:60'
>>> str(dt+timedelta(0,1))
'2009-01-01 00:00:00'
>>> str(dt+timedelta(0,2))
'2009-01-01 00:00:01'

maldito.

EDITAR - @Mark: Los documentos dicen "sí", pero el código dice "no tanto":

>>> time.strptime("2008-12-31 23:59:60","%Y-%m-%d %H:%M:%S")
(2008, 12, 31, 23, 59, 60, 2, 366, -1)
>>> time.mktime(time.strptime("2008-12-31 23:59:60","%Y-%m-%d %H:%M:%S"))
1230789600.0
>>> time.gmtime(time.mktime(time.strptime("2008-12-31 23:59:60","%Y-%m-%d %H:%M:%S")))
(2009, 1, 1, 6, 0, 0, 3, 1, 0)
>>> time.localtime(time.mktime(time.strptime("2008-12-31 23:59:60","%Y-%m-%d %H:%M:%S")))
(2009, 1, 1, 0, 0, 0, 3, 1, 0)

Pensaría que gmtime o localtime tomarían el valor devuelto por mktime y me devolverían la tupla original, con 60 como el número de segundos. Y esta prueba muestra que estos segundos intercalares pueden desaparecer ...

>>> a = time.mktime(time.strptime("2008-12-31 23:59:60","%Y-%m-%d %H:%M:%S"))
>>> b = time.mktime(time.strptime("2009-01-01 00:00:00","%Y-%m-%d %H:%M:%S"))
>>> a,b
(1230789600.0, 1230789600.0)
>>> b-a
0.0
PaulMcG
fuente
time.strftimemaneja los segundos intercalares : consulte la Nota 2: docs.python.org/library/time.html#time.strftime y la Nota 3: docs.python.org/library/datetime.html#strftime-behavior
Mark Rushakoff
Esto se debe a que el tiempo de Unix no maneja los segundos intercalares. Consulte en.wikipedia.org/wiki/Unix_time#History , mail-archive.com/[email protected]/msg00094.html y el propio POSIX.
"todos y cada uno de los días se contabilizarán exactamente por 86400 segundos" opengroup.org/onlinepubs/9699919799/basedefs/…
Los años bisiestos representan la diferencia entre el año solar y los 365 días pares, mientras que los segundos bisiestos son inherentemente diferentes y explican las diferencias causadas por factores externos como los terremotos. Esto los hace irregulares y no se pueden determinar de la misma manera que, por ejemplo, determinar el día de la semana en el que aterrizará el 3 de marzo de 2055.
David Woods
1
@DavidWoods: los segundos intercalares son para mantener UTC dentro de +/- 0.9 segundos desde UT1 (rotación de la Tierra). Hay 25 segundos bisiestos acumulados desde 1972 hasta 2012. Los terremotos son demasiado débiles para causarlo ( un solo terremoto puede introducir cambios de microsegundos, mil veces menos que una diferencia típica de milisegundos en la duración del día de 86400 SI segundos ).
jfs
5

Incluso el timemódulo básico puede manejar esto:

import time
time.localtime(time.time() + 24*3600)
u0b34a0f6ae
fuente
1
Esto falla en los límites del horario de verano en los Estados Unidos, porque en esos límites un día tendrá 23 horas y un día tendrá 25 horas. Esto tampoco tiene en cuenta los segundos intercalares.
Charles Wood
@CharlesWood: esta respuesta puede devolver una hora diferente que (en algunas zonas horarias) significa que puede devolver una fecha diferente (no mañana) pero siempre devuelve la hora exactamente 24 horas antes (la respuesta aceptada devuelve medianoche (horas desconocidas a partir de ahora) )). No veo cómo los segundos intercalares pueden cambiar el resultado aquí a menos que se llamen durante un segundo intercalar en sistemas donde 23:59:60 y 00:00:00 tienen la misma marca de tiempo.
jfs
Es cierto que siempre será dentro de 24 horas, pero esa no era la cuestión. OP quería saber cómo conseguir la fecha de mañana . Lo de los segundos intercalares fue simplemente quisquilloso;)
Charles Wood
@CharlesWood: sí. Acabo de aclarar que no regresa a las 23, 25 horas. Y sí, puede devolver una fecha incorrecta (no mañana, por ejemplo, para "2014-10-18 23:00:00" en la zona horaria "Brasil / Este"). Relacionado: Dada la hora actual en UTC, ¿cómo se determina la hora de inicio y finalización del día en una zona horaria en particular? .
jfs
@JFSebastian Correcto, solo estaba tratando de señalar que los días no siempre son de 24 horas . No es de extrañar que trabajar con fechas sea tan difícil; es difícil incluso comunicar sobre ellos: /
Charles Wood