获取明天日期的最干净、最符合Python风格的方式是什么?

185

如何以最干净、最Pythonic的方式获取明天的日期?肯定有比添加一天、处理月底日等更好的方法。

7个回答

344

datetime.date.today() + datetime.timedelta(days=1)可以解决问题。


59

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)

9

不过,没有处理闰秒的情况:

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

1
time.strftime 处理闰秒:请参见注释2:http://docs.python.org/library/time.html#time.strftime 和注释3:http://docs.python.org/library/datetime.html#strftime-behavior。 - Mark Rushakoff
这是因为Unix时间不处理闰秒。请参见http://en.wikipedia.org/wiki/Unix_time#History,http://www.mail-archive.com/leapsecs@rom.usno.navy.mil/msg00094.html和POSIX本身。 - Roger Pate
每一天都应该精确地计算86400秒。http://www.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_15 - Roger Pate
闰年考虑了太阳年和平均365天之间的差异,而闰秒则本质上不同,考虑到像地震这样的外部因素引起的差异。这使得它们是不规则的,并且不能像确定2055年3月3日星期几那样确定。 - David Woods
1
@DavidWoods:闰秒是为了让国际协调时间(UTC)与UT1(地球自转时间)之间的误差保持在正负0.9秒以内。从1972年到2012年,共积累了25个闰秒。地震过于微弱,无法引起闰秒的产生(单次地震可能会引入微秒级别的变化 -- 比一天持续时间中典型的毫秒差异小上千倍)。 - jfs

8

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

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

2
这在美国夏令时的边界上会失败,因为在那些边界上,一天将有23个小时,而另一天将有25个小时。此外,它也没有考虑闰秒。 - Charles Wood
1
@CharlesWood: 这个答案可能会返回一个不同的小时,这意味着它可能会返回一个不同的日期(而不是明天),但它总是返回正好比现在24小时的时间(被接受的答案返回午夜(未来几个小时))。我不知道闰秒如何改变这里的结果,除非在23:59:60和00:00:00具有相同时间戳的系统中调用。 - jfs
是的,从现在开始24小时后永远是明天,但这不是问题的关键。楼主想知道如何获取__明天的日期__。闰秒只是小题大作而已 ;) - Charles Wood
@CharlesWood:是的。我刚刚澄清了它不会返回23、25小时。而且,它可能会返回错误的日期(例如,在“巴西/东部”时区中,“2014-10-18 23:00:00”不是明天)。相关链接:在UTC的当前时间下,如何确定特定时区一天的开始和结束时间? - jfs
@J.F.Sebastian 对的,我只是想指出__一天并不总是24小时长__。难怪处理日期很困难;甚至交流都很难 :/ - Charles Wood
@Greg,不考虑夏令时问题,我认为添加24*3600秒并不优雅 - 我只想添加一天,而且我甚至不需要知道一天有多少小时/分钟/秒(尽管这可能会让日常生活有些困难)! - Simon MᶜKenzie

3

如果你只需要使用 today(),就像所选答案中示例的那样,那么使用它是没有任何问题的。

datetime.date.today() + datetime.timedelta(days=1)

另外,如果你或者与你一起工作的人在处理明天的日期时需要更高的精度,可以考虑使用datetime.now()代替 today()。这将使代码更简单、更易读:

datetime.datetime.now() + datetime.timedelta(days=1)

这将返回类似于以下内容:datetime.datetime(2022, 2, 17, 19, 50, 19, 984925)
优点在于您现在可以以简洁、易读的方式处理日期时间属性

class datetime.datetime

A combination of a date and a time. Attributes: year, month, day, hour, minute, second, microsecond, and tzinfo.

示例

你可以使用date()函数轻松将其转换为日期对象:

import datetime
tomorrow = datetime.datetime.now() + datetime.timedelta(days=1)
print(f"Tomorrow's date is {tomorrow.date()}")

tomorrow.date()很容易使用,而且任何阅读代码的人都能清楚地知道它返回的是明天的日期。以上输出如下所示:
明天的日期是2022-02-17

如果在您的代码后面仅需要当天的日期数字,则可以使用tomorrow.day

print(f"Tomorrow is the {tomorrow.day}rd")

这将返回类似于:
明天是 17 号

那个例子有点儿傻,但你可以看到访问这些属性有多么有用并且保持代码的可读性。很容易理解 tomorrow.day 返回日期号码。

需要处理明天日期开始的确切时间?现在可以替换小时、分钟、秒和微秒:

# Replace all attributes except day with 0.
midnight = tomorrow.replace(
    hour=0,
    minute=0,
    second=0,
    microsecond=0)
# Print midnight as the beginning of tomorrow's date.
print(f"{midnight}")

阅读上面的代码,可以明显看到哪些tomorrow的属性正在被替换。当打印midnight时,它会输出:
2022-02-17 00:00:00

需要知道离明天日期还有多长时间吗?现在这样的事情是可能的,简单易懂:

print(f"{midnight - datetime.datetime.now()}")

输出的是明天日期开始的微秒时间:

3:14:28.158331

人们可能有很多希望处理明天日期的方式。通过确保这些属性从一开始就可用,您可以编写更易读的代码并避免以后不必要的工作。


3

针对处理服务器时间戳的人

获取昨天的时间戳:

yesterdaytimestamp = datetime.datetime.today() + datetime.timedelta(days=-1)

获取今天的时间戳:
currenttimestamp = datetime.datetime.now().timestamp()

获取未来时间戳的方法:
tomorrowtimestamp = datetime.datetime.today() + datetime.timedelta(days=1)

打印:
print('\n Yesterday TimeStamp is : ', yesterdaytimestamp.timestamp(), 
    '\n Today TimeStamp is :', currenttimestamp, 
    '\n Tomorrow TimeStamp is: ', tomorrowtimestamp.timestamp())

输出:
Yesterday TimeStamp is :  1632842904.110993 
Today TimeStamp is       :  1632929304.111022 
Tomorrow TimeStamp is    :  1633015704.11103

0

如果您只想计算时间戳

import time
tomorrow = (int(time.time() / 86400) + 1) * 86400

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接