Python-calendar.timegm()与 time.mktime()

我好像很难理解这件事。

calendar.timegm()time.mktime()有什么区别?

假设我有一个 datetime.datetime,没有任何 tzinfo 附加,两者不应该给出相同的输出吗?它们不都给出了作为参数传递的时间和纪元之间的秒数吗?而且因为过去的日期没有 tzinfo,所以秒数不是一样的吗?

>>> import calendar
>>> import time
>>> import datetime
>>> d = datetime.datetime(2010, 10, 10)
>>> calendar.timegm(d.timetuple())
1286668800
>>> time.mktime(d.timetuple())
1286640000.0
>>>
59377 次浏览

从 UTC 时间戳 time.mktime从 < em > local time 而不是 UTC 转换转换。

8小时的结果差异与你所在地的时区完全一致。

time.mktime() 假设传递的元组在本地时间,calendar.timegm()假设它在 GMT/UTC。根据解释的不同,元组表示不同的时间,因此函数返回不同的值(从纪元开始的秒是基于 UTC 的)。

这两个值之间的差值应该等于本地时区的时区偏移量。

让我们考虑下面的例子,

>>> 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 对象,它是‘幼稚的’,并且没有关于本地时区的信息。

Time.mktime ()
将上述函数应用于 DateTime 对象将考虑“ Timezone”。
所以。对于上面的示例,当您为 time.gmtime ()提供时间“2022-05-2106: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”中减去该值,并返回所经过的总秒数()。

额外奖励
从 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

玩得开心:)