首頁>技術>

學習《Python Cookbook》第三版

你有一個安排在2021年3月21日早上9:30的電話會議,地點在上海。而你的朋友在芝加哥,那麼他應該在當地時間幾點參加這個會議呢?

對幾乎所有涉及到時區的問題,你都應該使用 pytz 模組。這個包提供了 Olson 時區資料庫,它是時區資訊的事實上的標準,在很多語言和作業系統裡面都可以找到。

關於Olson的介紹,可以檢視維基百科:https://en.wikipedia.org/wiki/Tz_database

pytz 模組一個主要用途是將 datetime 庫建立的簡單日期物件本地化。比如,下面如何表示一個芝加哥時間的示例:

from datetime import datetime, timedelta, datefrom pytz import timezonecat = datetime(2021, 3, 21, 9, 30, 0)print(cat)	# "2021-03-21 09:30:00"own = timezone('Asia/Shanghai')loc_cat = own.localize(cat)print(loc_cat)	# "2021-03-21 09:30:00+08:00"

一旦日期被本地化了,它就可以轉換為其他時區的時間了。為了得到芝加哥對應的時間,你可以這樣做:

chicago_cat = loc_cat.astimezone(timezone('America/Chicago'))print(chicago_cat)	#  "2021-03-20 20:30:00-05:00"

如果你打算在本地化日期上執行計算,你需要特別注意夏令時轉換和其他細節。比如,在2018年,美國標準夏令時時間開始於本地時間3月11日凌晨2:00(在那時,時間向前跳過一小時)。如果你正在執行本地計算,你會得到一個錯誤。比如:

d = datetime(2018, 3, 11, 1, 45, 0)print(d)	# "2018-03-11 01:45:00"central = timezone('America/Chicago')loc_d = central.localize(d)print(loc_d)	# "2018-03-11 01:45:00-06:00"later = loc_d + timedelta(minutes=30)print(later)	# "2018-03-11 02:15:00-06:00"

結果錯誤是因為它並沒有考慮在本地時間中有一小時的跳躍。為了修正這個錯誤,可以使用時區物件 normalize() 方法。比如:

later = central.normalize(loc_d + timedelta(minutes=30))print(later)	# "2018-03-11 03:15:00-05:00"

更多的年份的夏令時時間可以檢視: https://www.timeanddate.com/time/zone/usa/chicago

為了不讓你被這些東東弄的暈頭轉向,處理本地化日期的通常的策略先將所有日期轉換為 UTC 時間,並用它來執行所有的中間儲存和操作。比如:

import pytzfrom pytz import timezonecat = datetime(2018, 3, 11, 1, 45, 0)print(cat)	# "2018-03-11 01:45:00"chicago_zone = timezone('America/Chicago')chicago_cat = chicago_zone.localize(cat)print(chicago_cat)	# "2018-03-11 01:45:00-06:00"utc_chicago = chicago_cat.astimezone(pytz.utc)print(utc_chicago)	# "2018-03-11 07:45:00+00:00"

一旦轉換為 UTC,你就不用去擔心跟夏令時相關的問題了。因此,你可以跟之前一樣放心的執行常見的日期計算。當你想將輸出變為本地時間的時候,使用合適的時區去轉換下就行了。比如:

later_utc_chicago = utc_chicago + timedelta(minutes=30)print(later_utc_chicago.astimezone(chicago_zone))	# "2018-03-11 03:15:00-05:00"

當涉及到時區操作的時候,有個問題就是我們如何得到時區的名稱。比如,在這個例子中,我們如何知道“America/Chicago”就是芝加哥對應的時區名呢?為了查詢,可以使用 ISO 3166 國家程式碼作為關鍵字去查閱字典 pytz.country_timezones 。比如:

print(pytz.country_timezones['US'])"""['America/New_York', 'America/Detroit', 'America/Kentucky/Louisville', ...]"""

更多的時區區名可以檢視: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

5
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • leetcode1186_go_刪除一次得到子陣列最大和