Path: blob/master/ invest-robot-contest_TinkoffBotTwitch-main/venv/lib/python3.8/site-packages/pytz/tzfile.py
7771 views
'''1$Id: tzfile.py,v 1.8 2004/06/03 00:15:24 zenzen Exp $2'''34from datetime import datetime5from struct import unpack, calcsize67from pytz.tzinfo import StaticTzInfo, DstTzInfo, memorized_ttinfo8from pytz.tzinfo import memorized_datetime, memorized_timedelta91011def _byte_string(s):12"""Cast a string or byte string to an ASCII byte string."""13return s.encode('ASCII')1415_NULL = _byte_string('\0')161718def _std_string(s):19"""Cast a string or byte string to an ASCII string."""20return str(s.decode('ASCII'))212223def build_tzinfo(zone, fp):24head_fmt = '>4s c 15x 6l'25head_size = calcsize(head_fmt)26(magic, format, ttisgmtcnt, ttisstdcnt, leapcnt, timecnt,27typecnt, charcnt) = unpack(head_fmt, fp.read(head_size))2829# Make sure it is a tzfile(5) file30assert magic == _byte_string('TZif'), 'Got magic %s' % repr(magic)3132# Read out the transition times, localtime indices and ttinfo structures.33data_fmt = '>%(timecnt)dl %(timecnt)dB %(ttinfo)s %(charcnt)ds' % dict(34timecnt=timecnt, ttinfo='lBB' * typecnt, charcnt=charcnt)35data_size = calcsize(data_fmt)36data = unpack(data_fmt, fp.read(data_size))3738# make sure we unpacked the right number of values39assert len(data) == 2 * timecnt + 3 * typecnt + 140transitions = [memorized_datetime(trans)41for trans in data[:timecnt]]42lindexes = list(data[timecnt:2 * timecnt])43ttinfo_raw = data[2 * timecnt:-1]44tznames_raw = data[-1]45del data4647# Process ttinfo into separate structs48ttinfo = []49tznames = {}50i = 051while i < len(ttinfo_raw):52# have we looked up this timezone name yet?53tzname_offset = ttinfo_raw[i + 2]54if tzname_offset not in tznames:55nul = tznames_raw.find(_NULL, tzname_offset)56if nul < 0:57nul = len(tznames_raw)58tznames[tzname_offset] = _std_string(59tznames_raw[tzname_offset:nul])60ttinfo.append((ttinfo_raw[i],61bool(ttinfo_raw[i + 1]),62tznames[tzname_offset]))63i += 36465# Now build the timezone object66if len(ttinfo) == 1 or len(transitions) == 0:67ttinfo[0][0], ttinfo[0][2]68cls = type(zone, (StaticTzInfo,), dict(69zone=zone,70_utcoffset=memorized_timedelta(ttinfo[0][0]),71_tzname=ttinfo[0][2]))72else:73# Early dates use the first standard time ttinfo74i = 075while ttinfo[i][1]:76i += 177if ttinfo[i] == ttinfo[lindexes[0]]:78transitions[0] = datetime.min79else:80transitions.insert(0, datetime.min)81lindexes.insert(0, i)8283# calculate transition info84transition_info = []85for i in range(len(transitions)):86inf = ttinfo[lindexes[i]]87utcoffset = inf[0]88if not inf[1]:89dst = 090else:91for j in range(i - 1, -1, -1):92prev_inf = ttinfo[lindexes[j]]93if not prev_inf[1]:94break95dst = inf[0] - prev_inf[0] # dst offset9697# Bad dst? Look further. DST > 24 hours happens when98# a timzone has moved across the international dateline.99if dst <= 0 or dst > 3600 * 3:100for j in range(i + 1, len(transitions)):101stdinf = ttinfo[lindexes[j]]102if not stdinf[1]:103dst = inf[0] - stdinf[0]104if dst > 0:105break # Found a useful std time.106107tzname = inf[2]108109# Round utcoffset and dst to the nearest minute or the110# datetime library will complain. Conversions to these timezones111# might be up to plus or minus 30 seconds out, but it is112# the best we can do.113utcoffset = int((utcoffset + 30) // 60) * 60114dst = int((dst + 30) // 60) * 60115transition_info.append(memorized_ttinfo(utcoffset, dst, tzname))116117cls = type(zone, (DstTzInfo,), dict(118zone=zone,119_utc_transition_times=transitions,120_transition_info=transition_info))121122return cls()123124if __name__ == '__main__':125import os.path126from pprint import pprint127base = os.path.join(os.path.dirname(__file__), 'zoneinfo')128tz = build_tzinfo('Australia/Melbourne',129open(os.path.join(base, 'Australia', 'Melbourne'), 'rb'))130tz = build_tzinfo('US/Eastern',131open(os.path.join(base, 'US', 'Eastern'), 'rb'))132pprint(tz._utc_transition_times)133134135