Skip to content

Update legacy timezones

Benjamin Drung requested to merge bdrung/tzsetup:update-legacy into master

tzdata 2023c-8 moved the legacy timezones to tzdata-legacy. Update the timezones to not use any legacy names any more. Following Python code can be used:

import argparse
import pathlib
import re

def read_backwards_links(backwards_file: pathlib.Path) -> dict[str, str]:
    """Read backwards compatibility links from the tzdata backwards file."""
    backwards_links = {}
    for line in backwards_file.read_text(encoding="utf-8").splitlines():
        match = re.match(r"^Link\t(?P<target>\S+)\t+(?P<link_name>\S+)", line)
        if not match:
            continue
        backwards_links[match.group("link_name")] = match.group("target")
    return backwards_links

def read_tzdata_legacy_install(install_file: pathlib.Path) -> list[str]:
    paths = install_file.read_text("utf-8").strip().split("\n")
    return [path[19:] for path in paths if path.startswith("usr/share/zoneinfo/")]

def filter_legacy_links(
    backwards_links: dict[str, str], legacy_install: list[str]
) -> dict[str, str]:
    legacy_zones = {x for x in legacy_install if "/" in x}
    legacy_paths = [x for x in legacy_install if "/" not in x]

    legacy_links = {}
    for link_name, target in sorted(backwards_links.items()):
        if link_name in legacy_zones:
            legacy_links[link_name] = target
            continue
        for legacy_path in legacy_paths:
            if link_name.startswith(legacy_path):
                legacy_links[link_name] = target
                break
    return legacy_links

def update_links(legacy_links: dict[str, str], file: pathlib.Path) -> None:
    current_content = file.read_text("utf-8")
    content = current_content
    for link_name, target in sorted(legacy_links.items()):
        if "/" not in link_name:
            continue
        print(f"{link_name} -> {target}")
        content = re.sub(rf"\b{link_name}\b", target, content)
    if current_content != content:
        print(f"Updating {file}...")
        file.write_text(content, "utf-8")

def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("-t", "--tzdata-path", help="Path to extracted Debian source of tzdata")
    parser.add_argument("files", nargs="+")
    args = parser.parse_args()
    tzdata_path = pathlib.Path(args.tzdata_path)

    backwards_links = read_backwards_links(tzdata_path / "backward")
    legacy_install = read_tzdata_legacy_install(tzdata_path / "debian" / "tzdata-legacy.install")
    legacy_links = filter_legacy_links(backwards_links, legacy_install)
    for file in args.files:
        update_links(legacy_links, pathlib.Path(file))

if __name__ == "__main__":
    main()

The tzdata Debian packages needs to be available to convert the timezones:

./legacy_names.py -t ../tzdata debian/common.templates.in tzmap.override

Merge request reports

Loading