如何在 Python 中获取当前时间?
time 模块
time 模块提供了以“自纪元以来的秒数”为单位告诉我们时间的函数以及其他实用程序。
import time
Unix 纪元时间
这是您在数据库中保存时间戳时应采用的格式。它是一个简单的浮点数,可以转换为整数。它也适用于以秒为单位的算术运算,因为它表示自 1970 年 1 月 1 日 00:00:00 以来的秒数,并且相对于我们接下来要研究的其他时间表示而言,它是记忆之轻:
>>> time.time()
1424233311.771502
此时间戳不考虑闰秒,因此它不是线性的 - 闰秒被忽略。因此,虽然它不等同于国际 UTC 标准,但它很接近,因此对于大多数记录保存情况来说非常好。
但是,这对于人工调度来说并不理想。如果您有一个希望在某个时间点发生的未来事件,您需要将该时间与一个可以解析为datetime 对象或序列化datetime 对象的字符串一起存储(这些将是稍后介绍)。
time.ctime
您还可以以操作系统首选的方式表示当前时间(这意味着当您更改系统首选项时,它可能会发生变化,因此不要将其作为所有系统的标准,正如我所见其他人期望)。这通常是用户友好的,但通常不会导致可以按时间顺序排序的字符串:
>>> time.ctime()
'Tue Feb 17 23:21:56 2015'
您也可以使用 ctime 将时间戳合并为人类可读的形式:
>>> time.ctime(1424233311.771502)
'Tue Feb 17 23:21:51 2015'
这种转换也不利于记录保存(除了只能由人类解析的文本 - 并且随着光学字符识别和人工智能的改进,我认为这些案例的数量会减少)。
datetime模块
datetime 模块在这里也很有用:
>>> import datetime
datetime.datetime.now
datetime.now 是一个返回当前时间的类方法。它使用没有时区信息的time.localtime(如果没有给出,否则请参阅下面的时区感知)。它有一个在 shell 上回显的表示(允许您重新创建一个等效对象),但是当打印(或强制为str)时,它是人类可读的(并且几乎是 ISO)格式,并且字典排序是相当于按时间排序:
>>> datetime.datetime.now()
datetime.datetime(2015, 2, 17, 23, 43, 49, 94252)
>>> print(datetime.datetime.now())
2015-02-17 23:43:51.782461
日期时间的utcnow
您可以通过执行以下操作以 UTC 时间(全球标准)获取 datetime 对象:
>>> datetime.datetime.utcnow()
datetime.datetime(2015, 2, 18, 4, 53, 28, 394163)
>>> print(datetime.datetime.utcnow())
2015-02-18 04:53:31.783988
UTC 是几乎等同于 GMT 时区的时间标准。 (虽然 GMT 和 UTC 不会因夏令时而改变,但他们的用户可能会在夏季切换到其他时区,例如英国夏令时。)
datetime 时区感知
但是,到目前为止,我们创建的日期时间对象都不能轻松转换为不同的时区。我们可以使用pytz 模块解决这个问题:
>>> import pytz
>>> then = datetime.datetime.now(pytz.utc)
>>> then
datetime.datetime(2015, 2, 18, 4, 55, 58, 753949, tzinfo=<UTC>)
同样,在 Python 3 中,我们有 timezone 类,附加了一个 utc timezone 实例,这也使对象时区感知(但在没有方便的 pytz 模块的情况下转换到另一个时区作为练习给读者):
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2015, 2, 18, 22, 31, 56, 564191, tzinfo=datetime.timezone.utc)
我们看到我们可以轻松地从原始 UTC 对象转换为时区。
>>> print(then)
2015-02-18 04:55:58.753949+00:00
>>> print(then.astimezone(pytz.timezone('US/Eastern')))
2015-02-17 23:55:58.753949-05:00
您还可以使用 pytz timezone localize 方法或替换 tzinfo 属性(使用 replace,这是盲目地完成)来使天真的 datetime 对象感知,但这些是最后的手段而不是最佳实践:
>>> pytz.utc.localize(datetime.datetime.utcnow())
datetime.datetime(2015, 2, 18, 6, 6, 29, 32285, tzinfo=<UTC>)
>>> datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
datetime.datetime(2015, 2, 18, 6, 9, 30, 728550, tzinfo=<UTC>)
pytz 模块允许我们让 datetime 对象感知时区,并将时间转换为 pytz 模块中可用的数百个时区。
表面上可以将此对象序列化为 UTC 时间并将 那个 存储在数据库中,但与仅存储 Unix 纪元时间相比,它需要更多的内存并且更容易出错,我已演示过首先。
查看时间的其他方式更容易出错,尤其是在处理可能来自不同时区的数据时。您不希望字符串或序列化日期时间对象用于哪个时区。
如果您使用 Python 为用户显示时间,ctime 可以很好地工作,而不是在表格中(通常不能很好地排序),但可能在时钟中。但是,我个人建议,在 Python 中处理时间时,使用 Unix 时间,或者使用时区感知的 UTC datetime 对象。