协调世界时(英:Coordinated Universal Time ,法:Temps Universel Coordonné),又称世界统一时间,
世界标准时间,国际协调时间。英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC, 实际为英国伦敦本地时间.
UTC + 时差 = 本地时间(UTC + (+8000) = 北京时间)
datetime object 有2中类型:
下面就是一个继承tzinfo的子类, 然后实现不同时区间的转换的例子:
# encoding=utf-8
class UTC(datetime.tzinfo):
def __init__(self, utc):
utc = str(utc.strip().upper())
re_utc = re.compile(r'^([\+\-])([0-9]{1,2})\:([0-9]{1,2})$')
mt = re_utc.match(utc)
if mt:
minus = mt.group(1) == '-'
hours = int(mt.group(2))
minutes = int(mt.group(3))
if minus:
hours, minutes = -hours, -minutes
self._tzname = 'UTC{}'.format(utc)
self._utcoffset = datetime.timedelta(
hours=hours, minutes=minutes)
else:
raise ValueError('bad utc time zone')
def utcoffset(self, dt):
return self._utcoffset
def tzname(self, dt):
return self._tzname
# 夏令时
def dst(self, dt):
return datetime.timedelta(0)
def __str__(self):
return 'UTC tzinfo object ({})'.format(self._tzname)
__repr__ = __str__
# 默认的datetime不带时区信息
curdate = datetime.datetime.now()
print curdate.tzinfo
curdate = datetime.datetime.now(tz=UTC('-2:00')) # 西2区的当前时间
print curdate
print curdate.tzinfo
utc7 = UTC('+07:00')
utc8 = UTC('+08:00')
test_tuple = (2015, 10, 11, 14, 58)
# utc8_time, utc7_time 不同时区的同一时刻
utc8_time = datetime.datetime(*test_tuple, tzinfo=utc8)
utc7_time = utc8_time.astimezone(utc7)
print utc8_time
print utc7_time
timespan = utc8_time - utc7_time
print type(timespan), timespan.total_seconds()
获取tzinfo子类对象:
# 对于国家的时区列表
print pytz.country_timezones('cn') # [u'Asia/Shanghai', u'Asia/Urumqi']
tz = pytz.timezone('Asia/Shanghai')
上述获取tz对象都是LMT(local Mean Time)为本地平均时间的时区,并不是标准时间(Standard Time):
test_tuple = (2015, 10, 11, 14, 58)
dt = datetime.datetime(*test_tuple, tzinfo=tz)
print repr(dt)
# datetime.datetime(2015, 10, 11, 14, 58, tzinfo=<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>)
# dt有一个LMT(local Mean Time)为本地平均时间, 时间是+8:06, 比北京时间快6分钟
dt_cst = datetime.datetime(*test_tuple, tzinfo=utc8)
print dt_cst == dt # False
正确方法:
# 正确获取构造offset-aware类型datetime object的方法是:
# 使用timezone.localize()方法生成带时区的datetime, 不要通过构造函数中传入tzinfo的方式实现
dt2 = datetime.datetime(*test_tuple)
dt2 = tz.localize(dt2)
print repr(dt2)
# datetime.datetime(2015, 10, 11, 14, 58,
# tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>)
# dt2 变为CST(China Standard Time), 时间+8:00:00也是对的
print dt2 == dt_cst # True
pytz处理normalize函数处理夏令时, 特别是时区转换时.
eastern = pytz.timezone('US/Eastern')
dt3 = datetime.datetime(2002, 10, 27, 1, 0)
dt3 = eastern.localize(dt3)
print dt3 # 2002-10-27 01:00:00-05:00
dt4 = dt3 - datetime.timedelta(minutes=10)
print dt4 # 2002-10-27 00:50:00-05:00
dt5 = eastern.normalize(dt4)
print dt5 # 2002-10-27 01:50:00-04:00
print repr(dt4.tzinfo)
print repr(dt5.tzinfo)
# <DstTzInfo 'US/Eastern' EST-1 day, 19:00:00 STD>
# <DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>