| 6601 | return zip(a, b) |
| 6602 | |
| 6603 | class ZoneInfo(tzinfo): |
| 6604 | zoneroot = '/usr/share/zoneinfo' |
| 6605 | def __init__(self, ut, ti): |
| 6606 | """ |
| 6607 | |
| 6608 | :param ut: array |
| 6609 | Array of transition point timestamps |
| 6610 | :param ti: list |
| 6611 | A list of (offset, isdst, abbr) tuples |
| 6612 | :return: None |
| 6613 | """ |
| 6614 | self.ut = ut |
| 6615 | self.ti = ti |
| 6616 | self.lt = self.invert(ut, ti) |
| 6617 | |
| 6618 | @staticmethod |
| 6619 | def invert(ut, ti): |
| 6620 | lt = (array('q', ut), array('q', ut)) |
| 6621 | if ut: |
| 6622 | offset = ti[0][0] // SEC |
| 6623 | lt[0][0] += offset |
| 6624 | lt[1][0] += offset |
| 6625 | for i in range(1, len(ut)): |
| 6626 | lt[0][i] += ti[i-1][0] // SEC |
| 6627 | lt[1][i] += ti[i][0] // SEC |
| 6628 | return lt |
| 6629 | |
| 6630 | @classmethod |
| 6631 | def fromfile(cls, fileobj): |
| 6632 | if fileobj.read(4).decode() != "TZif": |
| 6633 | raise ValueError("not a zoneinfo file") |
| 6634 | fileobj.seek(32) |
| 6635 | counts = array('i') |
| 6636 | counts.fromfile(fileobj, 3) |
| 6637 | if sys.byteorder != 'big': |
| 6638 | counts.byteswap() |
| 6639 | |
| 6640 | ut = array('i') |
| 6641 | ut.fromfile(fileobj, counts[0]) |
| 6642 | if sys.byteorder != 'big': |
| 6643 | ut.byteswap() |
| 6644 | |
| 6645 | type_indices = array('B') |
| 6646 | type_indices.fromfile(fileobj, counts[0]) |
| 6647 | |
| 6648 | ttis = [] |
| 6649 | for i in range(counts[1]): |
| 6650 | ttis.append(struct.unpack(">lbb", fileobj.read(6))) |
| 6651 | |
| 6652 | abbrs = fileobj.read(counts[2]) |
| 6653 | |
| 6654 | # Convert ttis |
| 6655 | for i, (gmtoff, isdst, abbrind) in enumerate(ttis): |
| 6656 | abbr = abbrs[abbrind:abbrs.find(0, abbrind)].decode() |
| 6657 | ttis[i] = (timedelta(0, gmtoff), isdst, abbr) |
| 6658 | |
| 6659 | ti = [None] * len(ut) |
| 6660 | for i, idx in enumerate(type_indices): |