(tz_str)
| 625 | |
| 626 | |
| 627 | def _parse_tz_str(tz_str): |
| 628 | # The tz string has the format: |
| 629 | # |
| 630 | # std[offset[dst[offset],start[/time],end[/time]]] |
| 631 | # |
| 632 | # std and dst must be 3 or more characters long and must not contain |
| 633 | # a leading colon, embedded digits, commas, nor a plus or minus signs; |
| 634 | # The spaces between "std" and "offset" are only for display and are |
| 635 | # not actually present in the string. |
| 636 | # |
| 637 | # The format of the offset is ``[+|-]hh[:mm[:ss]]`` |
| 638 | |
| 639 | offset_str, *start_end_str = tz_str.split(",", 1) |
| 640 | |
| 641 | parser_re = re.compile( |
| 642 | r""" |
| 643 | (?P<std>[^<0-9:.+-]+|<[a-zA-Z0-9+-]+>) |
| 644 | (?: |
| 645 | (?P<stdoff>[+-]?\d{1,3}(?::\d{2}(?::\d{2})?)?) |
| 646 | (?: |
| 647 | (?P<dst>[^0-9:.+-]+|<[a-zA-Z0-9+-]+>) |
| 648 | (?P<dstoff>[+-]?\d{1,3}(?::\d{2}(?::\d{2})?)?)? |
| 649 | )? # dst |
| 650 | )? # stdoff |
| 651 | """, |
| 652 | re.ASCII|re.VERBOSE |
| 653 | ) |
| 654 | |
| 655 | m = parser_re.fullmatch(offset_str) |
| 656 | |
| 657 | if m is None: |
| 658 | raise ValueError(f"{tz_str} is not a valid TZ string") |
| 659 | |
| 660 | std_abbr = m.group("std") |
| 661 | dst_abbr = m.group("dst") |
| 662 | dst_offset = None |
| 663 | |
| 664 | std_abbr = std_abbr.strip("<>") |
| 665 | |
| 666 | if dst_abbr: |
| 667 | dst_abbr = dst_abbr.strip("<>") |
| 668 | |
| 669 | if std_offset := m.group("stdoff"): |
| 670 | try: |
| 671 | std_offset = _parse_tz_delta(std_offset) |
| 672 | except ValueError as e: |
| 673 | raise ValueError(f"Invalid STD offset in {tz_str}") from e |
| 674 | else: |
| 675 | std_offset = 0 |
| 676 | |
| 677 | if dst_abbr is not None: |
| 678 | if dst_offset := m.group("dstoff"): |
| 679 | try: |
| 680 | dst_offset = _parse_tz_delta(dst_offset) |
| 681 | except ValueError as e: |
| 682 | raise ValueError(f"Invalid DST offset in {tz_str}") from e |
| 683 | else: |
| 684 | dst_offset = std_offset + 3600 |
no test coverage detected
searching dependent graphs…