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