2013-03-16 206 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