我的问题:我需要将UTC时间元组转换为UTC时间戳。但我有一些困惑。
首先是一点信息:
time.mktime(tuple)
:此函数始终返回本地时间内的时间戳。
这是localtime()的反函数。它的参数是struct_time或完整的9元组,用本地时间表示时间,而不是UTC。
calendar.timegm(tuple)
:从提供的时间元组返回 UTC时间戳
获取时间模块中的gmtime()函数返回的时间元组,并返回相应的Unix时间戳值。事实上, time.gmtime()和timegm()彼此是反向的
现在让我们做一个测试:
>>> from datetime import datetime
>>> import time
>>> import calendar as cal
>>> utc_now = datetime.utcnow()
>>> now = datetime.now()
>>> utc_now
datetime.datetime(2013, 3, 16, 9, 17, 22, 489225)
>>> now
datetime.datetime(2013, 3, 16, 5, 17, 29, 736903)
>>> time.mktime(datetime.timetuple(utc_now)), time.mktime(datetime.timetuple(now))
(1363439842.0, 1363425449.0)
>>> cal.timegm(datetime.timetuple(utc_now)), cal.timegm(datetime.timetuple(now))
(1363425442, 1363411049)
为什么有四种不同的值?当我想将UTC时间元组转换为UTC时间戳时,哪一个是正确的?
UPDATTE
我想我已经找到了我的困惑的答案,所以让我解释一下。
首先,我们需要知道一些重要的事情:
有两种日期和时间对象:“天真”和“意识”。
知觉对象充分了解适用的算法和政治时间调整,例如时区和夏令时信息,以便相对于其他知晓对象定位自己。知觉对象用于表示不对解释[1]开放的特定时刻。
一个天真的对象没有足够的信息来明确地相对于其他日期/时间对象定位自己。 天真物体是代表协调世界时(UTC),当地时间还是其他时区的时间完全取决于程序,就像程序一样,是否特定数字代表米,里程或者质量。 天真的对象易于理解和使用,代价是忽略了现实的某些方面。
我们从datetime.utcnow()
或datetime.now()
获得的是"天真的"对象。这意味着,无论如何,返回的datetime
对象不会说出您当地时间或UTC时间的任何内容 - 它只表示"某些时间"。它只是封装了日期和时间。时间信息(年,月,日,小时,分钟,秒等)。您有责任将其与本地或UTC的概念联系起来。
所以,请记住,一个天真的日期时间对象只代表"某些时间"。 datetime.now()
函数返回"有些时间"等于你当前的时间,datetime.utcnow()
函数返回"有些时间"这是格林威治英格兰队的当前时间(也就是UTC)。
"有些时候"只是日期和价值的一个值时间。请注意,在地球的不同位置,有时"发生在不同的时间。例如,如果一段时间"价值是1月1日10:30,比格林威治英格兰当前时间早5个小时到现在纽约时间。
因此我们可以看到有两件事:一般的"一些时间"价值,以及那个"一段时间"在不同的时间"成为不同地点的当前时间。 (这里没有双关语,请继续阅读)
现在,让我们首先定义什么是" epoch"。我们知道"有些时候"只是时间的一般价值。然后,时代是一段时间"发生在格林威治英格兰,其中参数的值为:January 1 1970, 00:00:00
。
A"时间戳"没有。自纪元以来已经过去的秒数。这意味着当格林威治英格兰的时间为0
时,时间戳为Jan 1, 1970, 00:00:00
。但时间戳大约是。 (5 * 60 * 60),纽约的时间为Jan 1, 1970, 00:00:00
。
>>> tt = datetime.timetuple(datetime(1970, 1, 1, 0, 0, 0))
>>> cal.timegm(tt)
0
因此,我们可以看到相同的"一段时间"当我们更改位置时,Jan 1, 1970, 00:00:00
的值具有不同的时间戳。因此,当您谈论时间戳时,您还需要说出“#34;什么位置"是该位置与格林威治英格兰相关的时间戳,以及向东或向西的位置。该位置表示为"时区"。
现在,每个系统(计算机)都配置了一个时区,所有与该时区相关的时间戳都有效地成为了本地"。 UTC是全球参考。
所以,让我们假设你有一个X
值,而且#34;有些时候"转换为:
Y
时间戳Z
UTC时间戳那么这意味着Y
没有。一段时间后,必须经过几秒钟的时间"要成为你所在地的当前时间,并且Z
没有时间必须通过,以便在格林威治英格兰的当前时间成为"有些时间"。
现在,最后,让我们回到我们的职能mktime
和timegm
。这需要一个时间元组,这只是"某些时间"的另一种表示。请记住,我们通过了一个天真的时间,没有任何本地或UTC的概念。
让我们说X
是一个代表天真的时间元组"有些时间"。然后
mktime(X)
将返回号码。为了让你当地的当前时间成为那个"有些时间"和timegm(X)
将返回必须花费的秒数,以使格林威治英格兰队的当前时间等于#34;某段时间"。在上面的示例中,now
和utc_now
表示天真的"有些时间",当我们提供这些"某些时间"将值转换为mktime
和timegm
,它们只返回no。必须通过相应位置(您的位置和格林威治英格兰)的秒数,以使其当前时间为#34;某些时间"。
最后,回到我的问题:我需要将UTC时间元组转换为UTC时间戳。
首先,没有" UTC time-tuple"的概念。 - 它只是"一段时间"。如果我需要将其转换为UTC,我只需使用timegm
:
cal.timegm(datetime.timetuple(utc_now))
它将为我提供当前UTC时间的时间戳(即当前"某些时间"在格林威治英格兰)。
答案 0 :(得分:6)
实际上只有三个不同的值。这两个值:
1363425449.0 (time.mktime(datetime.timetuple(now))
1363425442 (cal.timegm(datetime.timetuple(utc_now)))
仅相差7秒,这是您在转储变量时最初看到的内容:
>>> utc_now
datetime.datetime(2013, 3, 16, 9, 17, 22, 489225)
>>> now
datetime.datetime(2013, 3, 16, 5, 17, 29, 736903)
(注意输出的秒部分中的22 vs 29。)
其他两个值只是错误的,因为您正在应用错误的参数 - 您使用UTC值而不是本地值调用time.mktime
,并且您正在调用cal.timegm
本地值而不是UTC值。文档清楚地说明了预期的内容 - 因此请确保只使用适当的值。你基本上看到你应该在不应该的时候(根据错误的位置在不同的方向)应用你当地的时间偏移(4个小时,根据其外观)。
当您诊断出这样的事情时,使用epochconverter.com将有助于您获得当前的Unix时间戳,这样您就可以将其与输出进行比较。