Il modo più pulito e più pitonico per ottenere l'appuntamento di domani?


120

Qual è il modo più pulito e più pitonico per ottenere l'appuntamento di domani? Deve esserci un modo migliore che aggiungerne uno al giorno, gestire i giorni alla fine del mese, ecc.

Risposte:


241

datetime.date.today() + datetime.timedelta(days=1) dovrebbe fare il trucco


39

timedelta può gestire l'aggiunta di giorni, secondi, microsecondi, millisecondi, minuti, ore o settimane.

>>> 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)

Come chiesto in un commento, i giorni bisestili non rappresentano un 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)

7

Nessuna gestione dei secondi intercalari anche se:

>>> 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'

maledettamente.

EDIT - @Mark: I documenti dicono "sì", ma il codice dice "non così 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)

Penso che gmtime o localtime prendano il valore restituito da mktime e mi restituiscano la tupla originale, con 60 come numero di secondi. E questo test mostra che questi secondi intercalari possono semplicemente svanire ...

>>> 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


Questo perché il tempo Unix non gestisce i secondi intercalari. Vedi en.wikipedia.org/wiki/Unix_time#History , mail-archive.com/leapsecs@rom.usno.navy.mil/msg00094.html e POSIX stesso.

"ogni giorno deve essere contabilizzato esattamente con 86400 secondi" opengroup.org/onlinepubs/9699919799/basedefs/…

Gli anni bisestili rappresentano la differenza tra l'anno solare e 365 giorni pari, mentre i secondi intercalari sono intrinsecamente diversi e tengono conto delle differenze causate da fattori esterni come i terremoti. Questo li rende irregolari e non possono essere determinati allo stesso modo, ad esempio, determinando il giorno della settimana in cui atterrerà il 3 marzo 2055.
David Woods

1
@DavidWoods: i secondi intercalari servono a mantenere l'UTC entro +/- 0,9 secondi da UT1 (rotazione terrestre). Ci sono 25 secondi intercalari accumulati dal 1972 al 2012. I terremoti sono troppo deboli per causarlo ( un singolo terremoto può introdurre cambiamenti di microsecondi, migliaia di volte meno di una differenza tipica di millisecondi nella durata del giorno da 86400 secondi SI ).
jfs

5

Anche il timemodulo di base può gestire questo:

import time
time.localtime(time.time() + 24*3600)

1
Questo fallisce sui confini dell'ora legale negli Stati Uniti, perché a quei confini un giorno avrà 23 ore e un giorno avrà 25 ore. Anche questo non tiene conto dei secondi intercalari.
Charles Wood

@CharlesWood: questa risposta può restituire un'ora diversa che (in alcuni fusi orari) significa che potrebbe restituire una data diversa (non domani) ma restituisce sempre l'ora che è esattamente 24 ore avanti (la risposta accettata restituisce mezzanotte (ore sconosciute da adesso )). Non vedo come i secondi intercalari possano modificare il risultato qui a meno che non vengano chiamati durante un secondo intercalare su sistemi in cui 23:59:60 e 00:00:00 hanno lo stesso timestamp.
jfs

È vero, saranno sempre 24 ore da adesso, ma non era quella la domanda. OP voleva sapere come ottenere la data di domani . La cosa dei secondi intercalari era solo pignoleria;)
Charles Wood

@CharlesWood: sì. Ho appena chiarito che non ritorna 23, 25 ore. E sì, potrebbe restituire una data sbagliata (non domani, ad esempio, per "2014-10-18 23:00:00" nel fuso orario "Brasile / Est"). Correlati: data l'ora corrente in UTC, come si determina l'ora di inizio e di fine della giornata in un particolare fuso orario? .
jfs

@JFSebastian Giusto, stavo solo cercando di sottolineare che i giorni non sono sempre lunghi 24 ore . Non c'è da stupirsi che lavorare con le date sia così difficile; è difficile persino parlare di loro: /
Charles Wood il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.