Самый чистый и питонический способ назначить свидание завтра?


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

Нет обработки дополнительных секунд tho:

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

штопать.

РЕДАКТИРОВАТЬ - @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.strftime и Примечание 3: docs.python.org/library/datetime.html#strftime-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 часа . Неудивительно, что работать с финиками так сложно; о них сложно даже говорить: /
Чарльз Вуд
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.