from datetime import tzinfo, timedelta, datetimeZERO = timedelta(0)HOUR = timedelta(hours=1)SECOND = timedelta(seconds=1)# A class capturing the platform's idea of local time.# (May result in wrong values on historical times in# timezones where UTC offset and/or the DST rules had# changed in the past.)import time as _timeSTDOFFSET = timedelta(seconds = -_time.timezone)if _time.daylight:DSTOFFSET = timedelta(seconds = -_time.altzone)else:DSTOFFSET = STDOFFSETDSTDIFF = DSTOFFSET - STDOFFSETclass LocalTimezone(tzinfo):def fromutc(self, dt):assert dt.tzinfo is selfstamp = (dt - datetime(1970, 1, 1, tzinfo=self)) // SECONDargs = _time.localtime(stamp)[:6]dst_diff = DSTDIFF // SECOND# Detect foldfold = (args == _time.localtime(stamp - dst_diff))return datetime(*args, microsecond=dt.microsecond,tzinfo=self, fold=fold)def utcoffset(self, dt):if self._isdst(dt):return DSTOFFSETelse:return STDOFFSETdef dst(self, dt):if self._isdst(dt):return DSTDIFFelse:return ZEROdef tzname(self, dt):return _time.tzname[self._isdst(dt)]def _isdst(self, dt):tt = (dt.year, dt.month, dt.day,dt.hour, dt.minute, dt.second,dt.weekday(), 0, 0)stamp = _time.mktime(tt)tt = _time.localtime(stamp)return tt.tm_isdst > 0Local = LocalTimezone()# A complete implementation of current DST rules for major US time zones.def first_sunday_on_or_after(dt):days_to_go = 6 - dt.weekday()if days_to_go:dt += timedelta(days_to_go)return dt# US DST Rules## This is a simplified (i.e., wrong for a few cases) set of rules for US# DST start and end times. For a complete and up-to-date set of DST rules# and timezone definitions, visit the Olson Database (or try pytz):# http://www.twinsun.com/tz/tz-link.htm# http://sourceforge.net/projects/pytz/ (might not be up-to-date)## In the US, since 2007, DST starts at 2am (standard time) on the second# Sunday in March, which is the first Sunday on or after Mar 8.DSTSTART_2007 = datetime(1, 3, 8, 2)# and ends at 2am (DST time) on the first Sunday of Nov.DSTEND_2007 = datetime(1, 11, 1, 2)# From 1987 to 2006, DST used to start at 2am (standard time) on the first# Sunday in April and to end at 2am (DST time) on the last# Sunday of October, which is the first Sunday on or after Oct 25.DSTSTART_1987_2006 = datetime(1, 4, 1, 2)DSTEND_1987_2006 = datetime(1, 10, 25, 2)# From 1967 to 1986, DST used to start at 2am (standard time) on the last# Sunday in April (the one on or after April 24) and to end at 2am (DST time)# on the last Sunday of October, which is the first Sunday# on or after Oct 25.DSTSTART_1967_1986 = datetime(1, 4, 24, 2)DSTEND_1967_1986 = DSTEND_1987_2006def us_dst_range(year):# Find start and end times for US DST. For years before 1967, return# start = end for no DST.if 2006 < year:dststart, dstend = DSTSTART_2007, DSTEND_2007elif 1986 < year < 2007:dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006elif 1966 < year < 1987:dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986else:return (datetime(year, 1, 1), ) * 2start = first_sunday_on_or_after(dststart.replace(year=year))end = first_sunday_on_or_after(dstend.replace(year=year))return start, endclass USTimeZone(tzinfo):def __init__(self, hours, reprname, stdname, dstname):self.stdoffset = timedelta(hours=hours)self.reprname = reprnameself.stdname = stdnameself.dstname = dstnamedef __repr__(self):return self.reprnamedef tzname(self, dt):if self.dst(dt):return self.dstnameelse:return self.stdnamedef utcoffset(self, dt):return self.stdoffset + self.dst(dt)def dst(self, dt):if dt is None or dt.tzinfo is None:# An exception may be sensible here, in one or both cases.# It depends on how you want to treat them. The default# fromutc() implementation (called by the default astimezone()# implementation) passes a datetime with dt.tzinfo is self.return ZEROassert dt.tzinfo is selfstart, end = us_dst_range(dt.year)# Can't compare naive to aware objects, so strip the timezone from# dt first.dt = dt.replace(tzinfo=None)if start + HOUR <= dt < end - HOUR:# DST is in effect.return HOURif end - HOUR <= dt < end:# Fold (an ambiguous hour): use dt.fold to disambiguate.return ZERO if dt.fold else HOURif start <= dt < start + HOUR:# Gap (a non-existent hour): reverse the fold rule.return HOUR if dt.fold else ZERO# DST is off.return ZEROdef fromutc(self, dt):assert dt.tzinfo is selfstart, end = us_dst_range(dt.year)start = start.replace(tzinfo=self)end = end.replace(tzinfo=self)std_time = dt + self.stdoffsetdst_time = std_time + HOURif end <= dst_time < end + HOUR:# Repeated hourreturn std_time.replace(fold=1)if std_time < start or dst_time >= end:# Standard timereturn std_timeif start <= std_time < end - HOUR:# Daylight saving timereturn dst_timeEastern = USTimeZone(-5, "Eastern", "EST", "EDT")Central = USTimeZone(-6, "Central", "CST", "CDT")Mountain = USTimeZone(-7, "Mountain", "MST", "MDT")Pacific = USTimeZone(-8, "Pacific", "PST", "PDT")
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。