17db96d56Sopenharmony_ciimport sys
27db96d56Sopenharmony_ciimport os
37db96d56Sopenharmony_ciimport struct
47db96d56Sopenharmony_cifrom array import array
57db96d56Sopenharmony_cifrom collections import namedtuple
67db96d56Sopenharmony_cifrom datetime import datetime
77db96d56Sopenharmony_ci
87db96d56Sopenharmony_cittinfo = namedtuple('ttinfo', ['tt_gmtoff', 'tt_isdst', 'tt_abbrind'])
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_ciclass TZInfo:
117db96d56Sopenharmony_ci    def __init__(self, transitions, type_indices, ttis, abbrs):
127db96d56Sopenharmony_ci        self.transitions = transitions
137db96d56Sopenharmony_ci        self.type_indices = type_indices
147db96d56Sopenharmony_ci        self.ttis = ttis
157db96d56Sopenharmony_ci        self.abbrs = abbrs
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ci    @classmethod
187db96d56Sopenharmony_ci    def fromfile(cls, fileobj):
197db96d56Sopenharmony_ci        if fileobj.read(4).decode() != "TZif":
207db96d56Sopenharmony_ci            raise ValueError("not a zoneinfo file")
217db96d56Sopenharmony_ci        fileobj.seek(20)
227db96d56Sopenharmony_ci        header = fileobj.read(24)
237db96d56Sopenharmony_ci        tzh = (tzh_ttisgmtcnt, tzh_ttisstdcnt, tzh_leapcnt,
247db96d56Sopenharmony_ci               tzh_timecnt, tzh_typecnt, tzh_charcnt) = struct.unpack(">6l", header)
257db96d56Sopenharmony_ci        transitions = array('i')
267db96d56Sopenharmony_ci        transitions.fromfile(fileobj, tzh_timecnt)
277db96d56Sopenharmony_ci        if sys.byteorder != 'big':
287db96d56Sopenharmony_ci            transitions.byteswap()
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_ci        type_indices = array('B')
317db96d56Sopenharmony_ci        type_indices.fromfile(fileobj, tzh_timecnt)
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_ci        ttis = []
347db96d56Sopenharmony_ci        for i in range(tzh_typecnt):
357db96d56Sopenharmony_ci            ttis.append(ttinfo._make(struct.unpack(">lbb", fileobj.read(6))))
367db96d56Sopenharmony_ci
377db96d56Sopenharmony_ci        abbrs = fileobj.read(tzh_charcnt)
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ci        self = cls(transitions, type_indices, ttis, abbrs)
407db96d56Sopenharmony_ci        self.tzh = tzh
417db96d56Sopenharmony_ci
427db96d56Sopenharmony_ci        return self
437db96d56Sopenharmony_ci
447db96d56Sopenharmony_ci    def dump(self, stream, start=None, end=None):
457db96d56Sopenharmony_ci        for j, (trans, i) in enumerate(zip(self.transitions, self.type_indices)):
467db96d56Sopenharmony_ci            utc = datetime.utcfromtimestamp(trans)
477db96d56Sopenharmony_ci            tti = self.ttis[i]
487db96d56Sopenharmony_ci            lmt = datetime.utcfromtimestamp(trans + tti.tt_gmtoff)
497db96d56Sopenharmony_ci            abbrind = tti.tt_abbrind
507db96d56Sopenharmony_ci            abbr = self.abbrs[abbrind:self.abbrs.find(0, abbrind)].decode()
517db96d56Sopenharmony_ci            if j > 0:
527db96d56Sopenharmony_ci                prev_tti = self.ttis[self.type_indices[j - 1]]
537db96d56Sopenharmony_ci                shift = " %+g" % ((tti.tt_gmtoff - prev_tti.tt_gmtoff) / 3600)
547db96d56Sopenharmony_ci            else:
557db96d56Sopenharmony_ci                shift = ''
567db96d56Sopenharmony_ci            print("%s UTC = %s %-5s isdst=%d" % (utc, lmt, abbr, tti[1]) + shift, file=stream)
577db96d56Sopenharmony_ci
587db96d56Sopenharmony_ci    @classmethod
597db96d56Sopenharmony_ci    def zonelist(cls, zonedir='/usr/share/zoneinfo'):
607db96d56Sopenharmony_ci        zones = []
617db96d56Sopenharmony_ci        for root, _, files in os.walk(zonedir):
627db96d56Sopenharmony_ci            for f in files:
637db96d56Sopenharmony_ci                p = os.path.join(root, f)
647db96d56Sopenharmony_ci                with open(p, 'rb') as o:
657db96d56Sopenharmony_ci                    magic =  o.read(4)
667db96d56Sopenharmony_ci                if magic == b'TZif':
677db96d56Sopenharmony_ci                    zones.append(p[len(zonedir) + 1:])
687db96d56Sopenharmony_ci        return zones
697db96d56Sopenharmony_ci
707db96d56Sopenharmony_ciif __name__ == '__main__':
717db96d56Sopenharmony_ci    if len(sys.argv) < 2:
727db96d56Sopenharmony_ci        zones = TZInfo.zonelist()
737db96d56Sopenharmony_ci        for z in zones:
747db96d56Sopenharmony_ci            print(z)
757db96d56Sopenharmony_ci        sys.exit()
767db96d56Sopenharmony_ci    filepath = sys.argv[1]
777db96d56Sopenharmony_ci    if not filepath.startswith('/'):
787db96d56Sopenharmony_ci        filepath = os.path.join('/usr/share/zoneinfo', filepath)
797db96d56Sopenharmony_ci    with open(filepath, 'rb') as fileobj:
807db96d56Sopenharmony_ci        tzi = TZInfo.fromfile(fileobj)
817db96d56Sopenharmony_ci    tzi.dump(sys.stdout)
82