2013-03-16 233 views
16

我的问题:我需要将UTC时间元转换为UTC时间戳。但我有一些混乱。Python:将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()得到的是“天真”的对象。这意味着返回的对象不会说出有关当地时间或UTC时间的任何事情 - 它只是表示“一段时间”。它只是封装日期&时间信息(年,月,日,时,分,秒等)。您有责任将其与本地或UTC的概念相关联。

所以,记住一个天真的日期时间对象只是代表“一段时间”。 datetime.now()函数返回等于您当前时间的“一段时间”,并且函数返回格林威治英格兰当前时间的“一段时间”(即UTC的时间)。

“一段时间”只是日期&时间的值。请注意,在地球上的不同位置,“一段时间”会在不同的时间发生。例如,如果“一段时间”的值是1月1日10:30,那么在格林威治英格兰目前的时间约5小时之前,它将成为纽约当前的时间。

因此,我们可以看到有两件事:通用的“一段时间”的值,以及“一段时间”成为当前时间在不同“时间”的不同位置的概念。 (这里没有双关,请继续阅读)

现在,我们先来定义什么是“时代”。我们知道“一段时间”只是时间的一个通用值。然后,这个时代是发生在格林威治英格兰的“一段时间”,其中参数的值是:January 1 1970, 00:00:00

“时间戳”是否定的。自史诗以来经过的秒数。这意味着在英格兰格林威治时间为Jan 1, 1970, 00:00:00的时间戳为0。但时间戳大约是。 (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相同的“一段时间”的价值有不同的时间戳,当我们改变位置。因此,当你谈论时间戳的时候,你还需要说与什么位置相关的时间戳,以及该位置与格林威治英格兰相关的向东或向西的位置。该位置表示为“时区”。

现在,每个系统(计算机)都配置了一个时区,并且与该时区相关的所有时间戳实际上成为“本地”。 UTC是全球参考。

所以,让我们说你有 “一段时间”,它转换成X值:

  • Z时间戳

    • Y时间戳在本地时间UTC

    那么这意味着那Y没有。几秒钟将不得不经过“一段时间”成为您所在位置的当前时间,并且不得不通过秒数,以使格林威治英格兰的当前时间成为“一段时间”。

    现在,终于让我们回到我们的功能mktimetimegm。这些需要一个时间元组,这只是“一段时间”的另一种表示。请记住,我们正在向他们传递一个天真的时间,它没有任何本地或UTC的概念。

    比方说,X是一个时间元组,代表一段天真的“一段时间”。然后

    • mktime(X)将返回no。为了让你当地的当前时间成为“一段时间”,必须经过几秒钟,并且
    • timegm(X)将返回必须花费的秒数,以使得格林威治英格兰的当前时间等于“一段时间”。

    在上述例子中,nowutc_now表示幼稚“一段时间”,而当我们喂这些“一段时间”值到mktimetimegm,它们简单地返回没有。必须通过相应位置(您的位置和格林威治英格兰)的秒数,以使其当前时间成为“一段时间”。


    最后,回到我的问题:我需要将UTC时间元组转换为UTC时间戳。

    首先,没有“UTC时间元组”的概念 - 这只是“一段时间”。如果我需要将其转换为UTC,我简单地使用timegm

    cal.timegm(datetime.timetuple(utc_now)) 
    

    ,这将给我当前UTC时间(即现在的“一段时间”,在格林威治英格兰)的时间戳。

  • +1

    非常丰富。谢谢。 – smartnut007 2014-02-07 19:47:50

    +0

    时代是'1970年1月1日,00:00:00 ** UTC + 0000 **。 1969年12月31日19:00:00 EST-0500'在纽约。无论当地时钟如何(纽约本地时钟将在晚上7点为POSIX时代显示),Epoch都是世界各地的同一时间实例。时间戳不取决于当地的时区 - 在任何特定时刻,它在世界各地都完全一样。 – jfs 2014-10-04 09:51:08

    +0

    相关:[在Python中将datetime.date转换为UTC时间戳](http://stackoverflow.com/q/8777753/4279) – jfs 2014-10-04 10:02:17

    回答

    6

    有效的只有三个不同的值。这两个值:

    >>> utc_now 
    datetime.datetime(2013, 3, 16, 9, 17, 22, 489225) 
    >>> now 
    datetime.datetime(2013, 3, 16, 5, 17, 29, 736903) 
    

    (注22 VS输出的​​秒部29:

    1363425449.0 (time.mktime(datetime.timetuple(now)) 
    1363425442 (cal.timegm(datetime.timetuple(utc_now))) 
    

    只有7秒,这是你最初看到的,当你甩了变量不同。 )

    其他两个值仅仅是错误的,因为您应用了错误的参数 - 您使用UTC值而不是本地值调用time.mktime,并且您使用本地值而不是UTC值调用cal.timegm 。文件清楚地说明了预期 - 所以确保你只使用适当的值。你基本上看到你的本地时间偏移(4小时,它的外观),当它不应该被应用时(根据错误的位置在不同的方向)。

    当你诊断这样的事情时,使用epochconverter.com会很有帮助,它会给你当前的Unix时间戳,所以你可以将它与你的输出进行比较。

    +0

    文档不会说参数是本地还是UTC。你为什么说其他两个值不正确? – treecoder 2013-03-16 09:41:15

    +1

    @good_computer:你是什么意思?你为'mktime'引用的文档*清楚地表明它应该是本地的,并且'timegm'引用的文档*表示这个元组应该是'gmtime'(即UTC)返回的类型。如果当某个函数需要本地时间或反之亦然时传递UTC值,则该函数将在不需要时应用本地/ UTC转换,或者* *在* *时应用*想要它。 (很遗憾,API本身无法检测到,但这就是生活...你需要小心) – 2013-03-16 10:30:54

    +0

    @good_computer:你的“一段时间”的概念在很多框架中也被称为“本地日期和时间” - 例如Joda Time中的LocalDateTime。这是一个没有关联时区的日期/时间。那么你是否还有问题,或者你是否排序? – 2013-03-16 11:17:26