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