Python: datetime.tzinfo
datetime.datetime & datetime.time 两个类构造时可传tzinfo参数, 都会把tzinfo绑定到self._tzinfo属性上, 可通过tzinfo属性访问
__str__依次调用一下方法
class tzinfo: """Abstract base class for time zone info classes. Subclasses must override the name(), utcoffset() and dst() methods. """ __slots__ = () def tzname(self, dt): "datetime -> string name of time zone." raise NotImplementedError("tzinfo subclass must override tzname()") def utcoffset(self, dt): "datetime -> timedelta, positive for east of UTC, negative for west of UTC" raise NotImplementedError("tzinfo subclass must override utcoffset()") def dst(self, dt): """datetime -> DST offset as timedelta, positive for east of UTC. Return 0 if DST not in effect. utcoffset() must include the DST offset. """ raise NotImplementedError("tzinfo subclass must override dst()") def fromutc(self, dt): "datetime in UTC -> datetime in local time." if not isinstance(dt, datetime): raise TypeError("fromutc() requires a datetime argument") if dt.tzinfo is not self: raise ValueError("dt.tzinfo is not self") dtoff = dt.utcoffset() if dtoff is None: raise ValueError("fromutc() requires a non-None utcoffset() " "result") # See the long comment block at the end of this file for an # explanation of this algorithm. dtdst = dt.dst() if dtdst is None: raise ValueError("fromutc() requires a non-None dst() result") delta = dtoff - dtdst if delta: dt += delta dtdst = dt.dst() if dtdst is None: raise ValueError("fromutc(): dt.dst gave inconsistent " "results; cannot convert") return dt + dtdst # Pickle support. def __reduce__(self): getinitargs = getattr(self, "__getinitargs__", None) if getinitargs: args = getinitargs() else: args = () getstate = getattr(self, "__getstate__", None) if getstate: state = getstate() else: state = getattr(self, "__dict__", None) or None if state is None: return (self.__class__, args) else: return (self.__class__, args, state)
datetime.tzinfo 抽象类 Abstract class
三个抽象方法: tzname, utcoffset, dst 子类必须override, 否则报 NotImplementedError
其子类也不是实例化的,其是为了构造datetime.datetime & datetime.time 准备的
调用datetime.datetime的tzname方法时,会调用实例的self._tzinfo的tzname方法,self._tzinfo是构造datetime.datetime实例时传递的tzinfo子类对象
因此dt就变成了datetime.datetime OR datetime.time 实例,这就是tzinfo类中的dt由来
import datetime
class UTC(datetime.tzinfo):
def __init__(self,offset=0):
self.__offset=offset
def utcoffset(self,dt):
return datetime.timedelta(hours=self.__offset)
def tzname(self,dt):
return 'UTC+%s dt: %s' % (self.__offset,[dt,id(dt)])
def dst(self,dt):
return datetime.timedelta(hours=self.__offset)
bj = datetime.datetime(2011, 11, 11, 0, 0, 0, tzinfo = UTC(8))
print(bj, id(bj))
print(bj.tzname())
print(bj.tzinfo)
bj.tzname()最终会调用UTC(8)实例的tzname方法
import datetime
class UTC(datetime.tzinfo):
def __init__(self,offset=0):
self.__offset=offset
def utcoffset(self,dt):
return datetime.timedelta(hours=self.__offset)
def tzname(self,dt):
return 'UTC+%s dt: %s' % (self.__offset,[dt,id(dt)])
def dst(self,dt):
return datetime.timedelta(hours=self.__offset)
#bj time
bj = datetime.datetime(2011, 11, 11, 0, 0, 0, tzinfo = UTC(8))
print("beijing time:",bj, id(bj))
print(bj.tzinfo)
#bangkok time
bangkok = datetime.datetime(2011,11,11,0,0,0,tzinfo = UTC(7))
print("bangkok time",bangkok)
#bj -> bangkok
print("beijing-time to bangkok-time:",bj.astimezone(UTC(7)),type(bj.astimezone(UTC(7))))
timespan=bj-bangkok
print("时差:",timespan,type(timespan))
bj & bangkok 时间由于tzinfo 的不同,产生了时差,相减生成datetime.timedelta对象
使用astimezone方法时,需要跟构造实例相同tzinfo子类对象,结果会转变时区