Найпростіший і найпітонічніший спосіб отримати завтрашнє побачення?


120

Який найчистіший і найпітонічніший спосіб отримати завтрашнє побачення? Має бути кращий спосіб, ніж додавати його в день, обробляти дні в кінці місяця тощо.

Відповіді:



39

timedelta може працювати з додаванням днів, секунд, мікросекунд, мілісекунд, хвилин, годин або тижнів.

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

Як запитують у коментарі, високосні дні не становлять проблем:

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

Немає обробки високосних секунд :

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

чорт.

EDIT - @Mark: Документи говорять "так", але код говорить "не так багато":

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

Я думаю, що gmtime або localtime прийме значення, повернене mktime, і поверне мені оригінальний кортеж, причому 60 - це кількість секунд. І цей тест показує, що ці високосні секунди можуть просто згасати ...

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

time.strftimeобробляє стрибкові секунди: див. Примітку 2: docs.python.org/library/time.html#time.strearch та Примітка 3: docs.python.org/library/datetime.html#strearch-behavior
Марк Рушакофф

Це пояснюється тим, що час Unix не справляється із стрибками секунди. Дивіться en.wikipedia.org/wiki/Unix_time#History , mail-archive.com/leapsecs@rom.usno.navy.mil/msg00094.html та сам POSIX.

"кожен день повинен обліковуватися рівно 86400 секунд" opengroup.org/onlinepubs/9699919799/basedefs/…

У високосні роки припадає різниця між сонячним роком і навіть 365 днів, тоді як високосні секунди за своєю суттю відрізняються і пояснюють відмінності, викликані зовнішніми факторами, такими як землетруси. Це робить їх нерегулярними і їх неможливо визначити так само, як, наприклад, визначити день тижня, на який вийде 3 березня 2055 року.
Девід Вудс

1
@DavidWoods: високосні секунди мають тримати UTC в межах +/- 0,9 секунди від UT1 (обертання Землі). З 1972 по 2012 рік накопичилося 25 стрибкових секунд. Землетруси занадто слабкі, щоб викликати це ( один землетрус може ввести мікросекундні зміни - у тисячі разів менше типової різниці мілісекунд у тривалості дня від 86400 СІ секунд ).
jfs

5

Навіть базовий timeмодуль може впоратися з цим:

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

1
Це не вдається на межі літнього часу в Сполучених Штатах, оскільки на цих межах один день матиме 23 години, а один день - 25 годин. Це також не враховує високосних секунд.
Чарльз Вуд

@CharlesWood: ця відповідь може повернути іншу годину, яка (у деяких часових поясах) означає, що вона може повернути іншу дату (не завтра), але завжди повертає час, який точно на 24 години вперед (прийнята відповідь повертається опівночі (невідомі години відтепер) )). Я не бачу, як високосні секунди можуть змінити результат тут, якщо вони не викликаються під час високосної секунди в системах, де 23:59:60 та 00:00:00 мають однакові часові позначки.
jfs

Щоправда, це завжди буде через 24 години, але це не було питанням. ОП хотіла знати, як отримати завтрашнє побачення . Річ із стрибних секунд була просто зажуреною;)
Чарльз Вуд

@CharlesWood: так. Я щойно уточнив, що це не повернеться 23, 25 години. І так, воно може повернути неправильну дату (не завтра, наприклад, "2014-10-18 23:00:00" у часовому поясі "Бразилія / Схід"). Пов’язано: З огляду на поточний час у UTC, як Ви визначаєте час початку та кінця дня у певному часовому поясі? .
jfs

@JFSebastian Правильно, я просто намагався зазначити, що дні не завжди тривають 24 години . Недарма працювати з датами так складно; важко навіть про них спілкуватися: /
Charles Wood
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.