⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tz.py

📁 Python的一个ORM,现在很火
💻 PY
📖 第 1 页 / 共 3 页
字号:
        # Finally, there are tzh_ttisgmtcnt UTC/local        # indicators, each stored as a one-byte value;        # they tell whether the transition times associated        # with local time types were specified as UTC or        # local time, and are used when a time zone file        # is used in handling POSIX-style time zone envi-        # ronment variables.        if ttisgmtcnt:            isgmt = struct.unpack(">%db" % ttisgmtcnt,                                  fileobj.read(ttisgmtcnt))        # ** Everything has been read **        # Build ttinfo list        self._ttinfo_list = []        for i in range(typecnt):            gmtoff, isdst, abbrind =  ttinfo[i]            # Round to full-minutes if that's not the case. Python's            # datetime doesn't accept sub-minute timezones. Check            # http://python.org/sf/1447945 for some information.            gmtoff = (gmtoff+30)//60*60            tti = _ttinfo()            tti.offset = gmtoff            tti.delta = datetime.timedelta(seconds=gmtoff)            tti.isdst = isdst            tti.abbr = abbr[abbrind:abbr.find('\x00', abbrind)]            tti.isstd = (ttisstdcnt > i and isstd[i] != 0)            tti.isgmt = (ttisgmtcnt > i and isgmt[i] != 0)            self._ttinfo_list.append(tti)        # Replace ttinfo indexes for ttinfo objects.        trans_idx = []        for idx in self._trans_idx:            trans_idx.append(self._ttinfo_list[idx])        self._trans_idx = tuple(trans_idx)        # Set standard, dst, and before ttinfos. before will be        # used when a given time is before any transitions,        # and will be set to the first non-dst ttinfo, or to        # the first dst, if all of them are dst.        self._ttinfo_std = None        self._ttinfo_dst = None        self._ttinfo_before = None        if self._ttinfo_list:            if not self._trans_list:                self._ttinfo_std = self._ttinfo_first = self._ttinfo_list[0]            else:                for i in range(timecnt-1,-1,-1):                    tti = self._trans_idx[i]                    if not self._ttinfo_std and not tti.isdst:                        self._ttinfo_std = tti                    elif not self._ttinfo_dst and tti.isdst:                        self._ttinfo_dst = tti                    if self._ttinfo_std and self._ttinfo_dst:                        break                else:                    if self._ttinfo_dst and not self._ttinfo_std:                        self._ttinfo_std = self._ttinfo_dst                for tti in self._ttinfo_list:                    if not tti.isdst:                        self._ttinfo_before = tti                        break                else:                    self._ttinfo_before = self._ttinfo_list[0]        # Now fix transition times to become relative to wall time.        #        # I'm not sure about this. In my tests, the tz source file        # is setup to wall time, and in the binary file isstd and        # isgmt are off, so it should be in wall time. OTOH, it's        # always in gmt time. Let me know if you have comments        # about this.        laststdoffset = 0        self._trans_list = list(self._trans_list)        for i in range(len(self._trans_list)):            tti = self._trans_idx[i]            if not tti.isdst:                # This is std time.                self._trans_list[i] += tti.offset                laststdoffset = tti.offset            else:                # This is dst time. Convert to std.                self._trans_list[i] += laststdoffset        self._trans_list = tuple(self._trans_list)    def _find_ttinfo(self, dt, laststd=0):        timestamp = ((dt.toordinal() - EPOCHORDINAL) * 86400                     + dt.hour * 3600                     + dt.minute * 60                     + dt.second)        idx = 0        for trans in self._trans_list:            if timestamp < trans:                break            idx += 1        else:            return self._ttinfo_std        if idx == 0:            return self._ttinfo_before        if laststd:            while idx > 0:                tti = self._trans_idx[idx-1]                if not tti.isdst:                    return tti                idx -= 1            else:                return self._ttinfo_std        else:            return self._trans_idx[idx-1]    def utcoffset(self, dt):        if not self._ttinfo_std:            return ZERO        return self._find_ttinfo(dt).delta    def dst(self, dt):        if not self._ttinfo_dst:            return ZERO        tti = self._find_ttinfo(dt)        if not tti.isdst:            return ZERO        # The documentation says that utcoffset()-dst() must        # be constant for every dt.        return self._find_ttinfo(dt, laststd=1).delta-tti.delta        # An alternative for that would be:        #        # return self._ttinfo_dst.offset-self._ttinfo_std.offset        #        # However, this class stores historical changes in the        # dst offset, so I belive that this wouldn't be the right        # way to implement this.            def tzname(self, dt):        if not self._ttinfo_std:            return None        return self._find_ttinfo(dt).abbr    def __eq__(self, other):        if not isinstance(other, tzfile):            return False        return (self._trans_list == other._trans_list and                self._trans_idx == other._trans_idx and                self._ttinfo_list == other._ttinfo_list)    def __ne__(self, other):        return not self.__eq__(other)    def __repr__(self):        return "%s(%s)" % (self.__class__.__name__, `self._filename`)    def __reduce__(self):        if not os.path.isfile(self._filename):            raise ValueError, "Unpickable %s class" % self.__class__.__name__        return (self.__class__, (self._filename,))class tzrange(datetime.tzinfo):    def __init__(self, stdabbr, stdoffset=None,                 dstabbr=None, dstoffset=None,                 start=None, end=None):        global relativedelta        if not relativedelta:            from dateutil import relativedelta        self._std_abbr = stdabbr        self._dst_abbr = dstabbr        if stdoffset is not None:            self._std_offset = datetime.timedelta(seconds=stdoffset)        else:            self._std_offset = ZERO        if dstoffset is not None:            self._dst_offset = datetime.timedelta(seconds=dstoffset)        elif dstabbr and stdoffset is not None:            self._dst_offset = self._std_offset+datetime.timedelta(hours=+1)        else:            self._dst_offset = ZERO        if start is None:            self._start_delta = relativedelta.relativedelta(                    hours=+2, month=4, day=1, weekday=relativedelta.SU(+1))        else:            self._start_delta = start        if end is None:            self._end_delta = relativedelta.relativedelta(                    hours=+1, month=10, day=31, weekday=relativedelta.SU(-1))        else:            self._end_delta = end    def utcoffset(self, dt):        if self._isdst(dt):            return self._dst_offset        else:            return self._std_offset    def dst(self, dt):        if self._isdst(dt):            return self._dst_offset-self._std_offset        else:            return ZERO    def tzname(self, dt):        if self._isdst(dt):            return self._dst_abbr        else:            return self._std_abbr    def _isdst(self, dt):        if not self._start_delta:            return False        year = datetime.date(dt.year,1,1)        start = year+self._start_delta        end = year+self._end_delta        dt = dt.replace(tzinfo=None)        if start < end:            return dt >= start and dt < end        else:            return dt >= start or dt < end    def __eq__(self, other):        if not isinstance(other, tzrange):            return False        return (self._std_abbr == other._std_abbr and                self._dst_abbr == other._dst_abbr and                self._std_offset == other._std_offset and                self._dst_offset == other._dst_offset and                self._start_delta == other._start_delta and                self._end_delta == other._end_delta)    def __ne__(self, other):        return not self.__eq__(other)    def __repr__(self):        return "%s(...)" % self.__class__.__name__    __reduce__ = object.__reduce__class tzstr(tzrange):        def __init__(self, s):        global parser        if not parser:            from dateutil import parser        self._s = s        res = parser._parsetz(s)        if res is None:            raise ValueError, "unknown string format"        # We must initialize it first, since _delta() needs        # _std_offset and _dst_offset set. Use False in start/end        # to avoid building it two times.        tzrange.__init__(self, res.stdabbr, res.stdoffset,                         res.dstabbr, res.dstoffset,                         start=False, end=False)        self._start_delta = self._delta(res.start)        if self._start_delta:            self._end_delta = self._delta(res.end, isend=1)    def _delta(self, x, isend=0):        kwargs = {}        if x.month is not None:            kwargs["month"] = x.month            if x.weekday is not None:                kwargs["weekday"] = relativedelta.weekday(x.weekday, x.week)                if x.week > 0:                    kwargs["day"] = 1                else:                    kwargs["day"] = 31            elif x.day:                kwargs["day"] = x.day        elif x.yday is not None:            kwargs["yearday"] = x.yday        elif x.jyday is not None:            kwargs["nlyearday"] = x.jyday        if not kwargs:            # Default is to start on first sunday of april, and end            # on last sunday of october.            if not isend:                kwargs["month"] = 4                kwargs["day"] = 1                kwargs["weekday"] = relativedelta.SU(+1)            else:                kwargs["month"] = 10                kwargs["day"] = 31                kwargs["weekday"] = relativedelta.SU(-1)        if x.time is not None:            kwargs["seconds"] = x.time        else:            # Default is 2AM.            kwargs["seconds"] = 7200        if isend:            # Convert to standard time, to follow the documented way            # of working with the extra hour. See the documentation            # of the tzinfo class.            delta = self._dst_offset-self._std_offset            kwargs["seconds"] -= delta.seconds+delta.days*86400        return relativedelta.relativedelta(**kwargs)    def __repr__(self):        return "%s(%s)" % (self.__class__.__name__, `self._s`)class _tzicalvtzcomp:    def __init__(self, tzoffsetfrom, tzoffsetto, isdst,                       tzname=None, rrule=None):        self.tzoffsetfrom = datetime.timedelta(seconds=tzoffsetfrom)        self.tzoffsetto = datetime.timedelta(seconds=tzoffsetto)        self.tzoffsetdiff = self.tzoffsetto-self.tzoffsetfrom        self.isdst = isdst        self.tzname = tzname        self.rrule = rrule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -