Python构造时区感知日期时间
示例
默认情况下,所有datetime对象都是幼稚的。要使其具有时区意识,您必须附加一个tzinfo对象,该对象提供UTC偏移量和时区缩写作为日期和时间的函数。
固定偏移时区
对于与UTC有固定偏移量的时区,在Python3.2+中,该datetime模块提供了timezone类的具体实现,该类tzinfo带有timedelta和一个(可选)name参数:
Python3.x3.2from datetime import datetime, timedelta, timezone
JST = timezone(timedelta(hours=+9))
dt = datetime(2015, 1, 1, 12, 0, 0, tzinfo=JST)
print(dt)
#2015-01-0112:00:00+09:00
print(dt.tzname())
#UTC+09:00
dt = datetime(2015, 1, 1, 12, 0, 0, tzinfo=timezone(timedelta(hours=9), 'JST'))
print(dt.tzname)
#'JST'
对于3.2之前的Python版本,有必要使用第三方库,例如dateutil。dateutil提供了一个等效的类,tzoffset(从2.5.3版开始)采用形式为的参数,其中以秒为单位指定:dateutil.tz.tzoffset(tzname,offset)offset
Python3.x3.2Python2.x2.7from datetime import datetime, timedelta
from dateutil import tz
JST = tz.tzoffset('JST', 9 * 3600) #每小时3600秒
dt = datetime(2015, 1, 1, 12, 0, tzinfo=JST)
print(dt)
#2015-01-0112:00:00+09:00
print(dt.tzname)
#'JST'
夏令时的区域
对于具有夏令时的区域,python标准库不提供标准类,因此有必要使用第三方库。pytz并且dateutil是提供时区类的流行图书馆。
除了静态时区,dateutil还提供使用夏时制的时区类(请参阅该tz模块的文档)。您可以使用该方法获取时区对象,然后将其直接传递给构造函数:tz.gettz()datetime
from datetime import datetime
from dateutil import tz
local = tz.gettz() #当地时间
PT = tz.gettz('US/Pacific') #太平洋时间
dt_l = datetime(2015, 1, 1, 12, tzinfo=local) #我在美国东部时间
dt_pst = datetime(2015, 1, 1, 12, tzinfo=PT)
dt_pdt = datetime(2015, 7, 1, 12, tzinfo=PT) #DST是自动处理的
print(dt_l)
#2015-01-0112:00:00-05:00
print(dt_pst)
#2015-01-0112:00:00-08:00
print(dt_pdt)
#2015-07-0112:00:00-07:00
注意:从2.5.3版开始,dateutil不能正确处理不明确的日期时间,并且始终默认为较晚的日期。无法使用dateutil时区表示表示时间的对象,例如2015-11-011:30EDT-4,因为这是在夏令时过渡期间。
使用时,所有的边缘案件得到妥善处理pytz,但pytz时区应该不是通过构造函数直接连接到时区。而是pytz应使用时区的localize方法附加时区:
from datetime import datetime, timedelta
import pytz
PT = pytz.timezone('US/Pacific')
dt_pst = PT.localize(datetime(2015, 1, 1, 12))
dt_pdt = PT.localize(datetime(2015, 11, 1, 0, 30))
print(dt_pst)
#2015-01-0112:00:00-08:00
print(dt_pdt)
#2015-11-0100:30:00-07:00
请注意,如果您在pytz-aware时区上执行日期时间算术,则必须以UTC执行计算(如果您希望绝对经过的时间),或者必须调用normalize()结果:
dt_new = dt_pdt + timedelta(hours=3) #这应该是太平洋标准时间上午2:30
print(dt_new)
#2015-11-0103:30:00-07:00
dt_corrected = PT.normalize(dt_new)
print(dt_corrected)
#2015-11-0102:30:00-08:00