最干净,最Pythonic的方式来获取明天的约会?


120

获取明天约会的最干净,最Python方式是什么?必须有比在一天中增加一天,在月末处理天等等的更好的方法。

Answers:



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)

如评论中所问,leap日没有问题:

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

该死的

编辑-@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秒为单位返回给我原始的元组。该测试表明这些leap秒会逐渐消失...

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


这是因为Unix时间无法处理leap秒。见en.wikipedia.org/wiki/Unix_time#Historymail-archive.com/leapsecs@rom.usno.navy.mil/msg00094.html和POSIX本身。

“每一天,由恰好86400秒被占” opengroup.org/onlinepubs/9699919799/basedefs/...

years年是太阳年与甚至365天之间的差异,而leap秒本质上是不同的,并且是由地震等外部因素引起的差异。这使它们不规则,无法以与确定2055年3月3日所在的星期几相同的方式确定。
大卫·伍兹

1
@DavidWoods:leap秒将使UTC与UT1(地球旋转)保持在+/- 0.9秒内。从1972年到2012年,累积了25秒钟的leap秒。地震太弱而无法引起地震一次地震可能会引起微秒的变化,这比白天持续时间(86400 SI秒的典型毫秒差小千倍)。
jfs

5

即使是基本time模块也可以处理此问题:

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

1
这在美国的夏令时边界上是失败的,因为在这些边界上,一天将有23个小时,而一天将有25个小时。这也没有考虑leap秒。
查尔斯·伍德

@CharlesWood:此答案可能返回不同的小时(在某些时区),意味着它可能返回不同的日期(不是明天),但始终返回正好提前24小时的时间(接受的答案返回午夜(从现在开始未知的小时数) ))。我看不到leap秒如何更改此处的结果,除非在23:59:60和00:00:00具有相同时间戳的系统上a秒调用。
jfs

没错,从现在开始总是24小时,但这不是问题。OP想知道如何确定明天的日期。seconds秒只是在挑剔;)
查尔斯·伍德

@CharlesWood:是的。我刚刚澄清说,它不会在23、25小时后返回。是的,它可能返回错误的日期(例如,明天(巴西/东部)时区的“ 2014-10-18 23:00:00”不是明天)。相关:考虑到UTC的当前时间,您如何确定特定时区中一天的开始和结束时间?
jfs 2014年

@JFSebastian对,我只是想指出几天并不总是24小时。难怪处理日期是如此的困难。甚至很难就他们进行沟通:/
Charles Wood
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.