2015-12-02 66 views
5

我一直在python/django中大量使用日期。爲了解決各種使用案例,我一直在盲目地嘗試各種不同的方法,直到其中一個工作,而沒有學習各種功能如何工作的邏輯。Django/python - 消除關於日期和時區感知的混淆

現在是關鍵時刻。我想問幾個關於django/python中錯綜複雜的日期和時區的問題。

如何解釋已有時區的datetime對象?

爲了澄清,讓我們說我做到以下幾點:

>>> generate_a_datetime() 
datetime.datetime(2015, 12, 2, 0, 0, tzinfo=<DstTzInfo 'Canada/Eastern' LMT-1 day, 18:42:00 STD>) 
>>> 

控制檯輸出似乎模棱兩可的對我說:

Q1)這datetime對象說,這是2015-12-02 - 什麼是generate_a_datetime功能說服力我?是否說「一個站在加拿大東部的人看他的日曆會看到」2015-12-02「?或是否意味着」這是「2015-12-02 UTC」......但別忘了調整這個東部加拿大時區「

django.utils.timezone.make_aware混淆了我

例如:!

>>> from django.utils import timezone 
>>> import pytz 
>>> tz = pytz.timezone('Canada/Eastern') 
>>> now_unaware = datetime.datetime.now() 
>>> now_aware_with_django = timezone.make_aware(now_unaware, tz) 
>>> now_aware_with_datetime = now_unaware.replace(tzinfo=tz) 
>>> now_unaware 
datetime.datetime(2015, 12, 2, 22, 1, 19, 564003) 
>>> now_aware_with_django 
datetime.datetime(2015, 12, 2, 22, 1, 19, 564003, tzinfo=<DstTzInfo 'Canada/Eastern' EST-1 day, 19:00:00 STD>) 
>>> now_aware_with_datetime 
datetime.datetime(2015, 12, 2, 22, 1, 19, 564003, tzinfo=<DstTzInfo 'Canada/Eastern' LMT-1 day, 18:42:00 STD>) 
>>> 

的對象now_aware_with_djangonow_aware_with_datetime似乎表現同樣,但他們的控制檯輸出表明他們是不同的。

Q2)是什麼now_aware_with_djangonow_aware_with_datetime之間的區別?

Q3)我怎麼知道我是否需要使用timezone.make_awaredatetime.replace

天真的日期時間與UTC日期時間

UTC意味着是時間價值沒有變化。 「天真」似乎意味着時間沒有與時區相關聯。

Q4)樸素和UTC日期有什麼區別?看起來他們完全一樣 - 既沒有對實際時間值進行任何轉換。

Q5)我怎麼知道我什麼時候想要使用天真的時間,以及何時想使用UTC時間?

如果我能得到一個答案,所有5個問題將是積極出色的。非常感謝!

回答

1

Q1)DateTime對象說,這是2015年12月2日 - 什麼是generate_a_datetime功能告訴我?是否這樣說:「一個站在加拿大東部的人看他的日曆會看到」2015-12-02「?或者這意味着」這是2015-12-02 UTC「...但是不要忘記調整它到加拿大東部時區!「

第一種解釋是正確的。該時區感知日期時間已經被「調整」爲您和tzinfo只是告訴你哪個時區是在指定。

Q2)是什麼now_aware_with_djangonow_aware_with_datetime之間的區別?

對於第一種情況下,你創建它代表了時間的「天真」一個相同點日期時間,而這假設天真的一次是在您的本地時區。

對於第二種情況,您說的是那個天真的人已經在您提供的時區,然後您只需粘貼tzinfo。

Q3)我怎麼知道我是否需要使用timezone.make_awaredatetime.replace?

嘛,因爲他們做不同的事情,你需要知道你正在試圖做的知道哪些使用什麼。如果你想從一個天真的時區(在你當地的時間)轉換到不同的時區,你可以使用make_aware。如果你已經知道你的天真日期時間的,你只需要使用替換(或者看localizepytz,這對此任務有點小心)。

注意:通常如果你有任何天真的日期時間在第一時間徘徊,你以前做錯了什麼,你應該趕上更早。嘗試讓他們知道你的應用程序的邊界 - 我會在第五季度對此進行更多的說明。

Q4)天真與UTC日期有什麼區別?看起來他們完全一樣 - 既沒有對實際時間值進行任何轉換。

一個天真的日期時間只是一個日期時間,它不告訴你它在什麼時區。它不一定是UTC,它可能是任何東西。它與bytestrings和unicode相似 - 你必須知道什麼是編碼來說明解碼的字節在說什麼。對於一個天真的日期時間,你必須知道它在什麼時區,然後才能說出它實際表示的時間。所以在這個意義上,UTC日期時間提供的信息比天真的日期時間更多。

UTC是協調世界時,怪怪首字母縮寫的法國人。時區通常被定義爲與UTC時間相差整整數小時,並且出於所有實際目的,您可以將UTC視爲與UTC不同的時區0小時。這就像是GMT沒有任何夏令時的廢話。

Q5)我怎麼知道我什麼時候想要使用天真的時間,以及何時想使用UTC時間?

對此有不同意見。我的建議是始終在您的應用程序中使用UTC中的所有內容(並且僅在數據庫中存儲UTC!)。當任何日期時間數據輸入您的應用程序時,它會進入您的應用程序,請確保它已正確轉換爲UTC。這也意味着,裏面你的應用程序使用datetime.now()(這是一個天真的日期時間與「失蹤」tzinfo應該是本地時區的機器),而不是使用datetime.utcnow()(這是一個天真的日期時間在UTC),甚至更好datetime.now(tz=pytz.utc)(這是時區知道)。

只在應用的「顯示」一端更改爲本地時區。您通常可以使用模板標籤或甚至客戶端js來做到這一點。

+0

完美。 +1爲實用建議! –