让我们考虑下面的例子:
>>> import datetime
>>> import time
>>> import calendar
>>> utc_time_now = datetime.datetime.utcnow()
>>> utc_time_now
datetime.datetime(2022, 5, 21, 6, 47, 33, 929433)
>>> time.mktime(utc_time_now.timetuple())
1653095853.0
>>> calendar.timegm(utc_time_now.timetuple())
1653115653
>>> time.tzname
('IST', 'IST')
>>> time.strftime("%z", time.gmtime())
'+0530'
>>> (1653115653-1653095853)
19800
在解释开始之前,请注意,'datetime.datetime.utcnow()' 返回的是一个 DateTime 对象,它是“naive”的,并且没有关于您本地时区的任何信息。
time.mktime()
将上述函数应用于 DateTime 对象会考虑到“时区”。因此,根据上面的例子,当您向 time.gmtime() 提供时间“2022-05-21 06:47:33”时,它会认为这个时间实际上不是在 UTC 中,而是在您的本地时区(我的情况下是'IST')。
在我的情况下,时区是 'IST',它比 UTC 时区提前 +05:30(5 小时,30 分钟)。
所以为了返回 UTC 时区中的时代,它会从 datetime 对象的时间戳计算中减去 +05:30(19800 秒)。
因此,它返回时间戳(1653095853.0),这比原始的 UTC 时代秒数(1653115653)少 19800 秒。
注意:如果您的时区是负的(例如 -05:30),它会在最终时代计算中添加 19800 秒。因此,您将看到 time.gmtime() 时间戳比 UTC 时代时间戳大 19800 秒。
calendar.timegm()
它返回相应的 Unix 时间戳值,假设一个纪元为 1970-01-01。因此,在 DateTime 对象中不进行任何额外的调整。
它获取任何 DateTime 对象值,将其从纪元时间“1970-01-01”中减去并返回经过的总秒数(seconds())。
BONUS 奖励
从您的 UTC DateTime 对象获取时间戳纪元毫秒。
第一种方法:
>>> utc_time_now
datetime.datetime(2022, 5, 21, 7, 16, 34, 938547)
>>> int((calendar.timegm(utc_time_now.timetuple()) + (utc_time_now.microsecond/1e6))*1000.0)
1653117394938
第二种方法:
>>> utc_time_epoch = datetime.datetime.utcfromtimestamp(0)
>>> utc_time_epoch
datetime.datetime(1970, 1, 1, 0, 0)
>>> utc_time_now = datetime.datetime.utcnow()
>>> utc_time_now
datetime.datetime(2022, 5, 21, 7, 16, 34, 938547)
>>> elapsed_time = utc_time_now - utc_time_epoch
>>> elapsed_time
datetime.timedelta(19133, 26194, 938547)
>>> int(elapsed_time.total_seconds() * 1000.0)
1653117394938
祝你玩得愉快 :)