forked from collective/icalendar
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerate_windows_to_olson_mapping.py
More file actions
75 lines (61 loc) · 2.8 KB
/
Copy pathgenerate_windows_to_olson_mapping.py
File metadata and controls
75 lines (61 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
"""Generate the Windows to Olson timezone mapping module windows_to_olson.py."""
# Source - https://stackoverflow.com/a/16157049
# Posted by unutbu, modified by community. See post 'Timeline' for change history
# Retrieved 2026-07-16, License - CC BY-SA 3.0
# Source - https://stackoverflow.com/a/10469748
# Posted by mzjn, modified by community. See post 'Timeline' for change history
# Retrieved 2026-07-16, License - CC BY-SA 3.0
import json
import re
import urllib.request as req
import xml.etree.ElementTree as ET
from pathlib import Path
CLDR_PATH = "common/supplemental/windowsZones.xml"
# GitHub returns commits newest-first by default; [0] is the latest commit
# touching this file.
commits_url = f"https://api.github.com/repos/unicode-org/cldr/commits?path={CLDR_PATH}&sha=main&per_page=1"
with req.urlopen(commits_url) as response: # noqa: S310
commit = json.load(response)[0]
version = commit["sha"]
version_date = commit["commit"]["committer"]["date"][:10]
if re.fullmatch(r"[0-9a-f]{40}", version) is None:
raise ValueError(f"Invalid CLDR commit SHA: {version!r}")
if re.fullmatch(r"[0-9]{4}-[0-9]{2}-[0-9]{2}", version_date) is None:
raise ValueError(f"Invalid CLDR commit date: {version_date!r}")
# Fetch the XML from the commit recorded in the generated module. Using the
# commit instead of `main` ensures that the data and version cannot diverge if
# CLDR changes between the two requests.
url = f"https://raw.githubusercontent.com/unicode-org/cldr/{version}/{CLDR_PATH}"
with req.urlopen(url) as response: # noqa: S310
xml_content = response.read()
# Parse the XML file and extract the timezone mapping.
result = {}
tree = ET.fromstring(xml_content) # noqa: S314
for zone in tree.findall(".//mapZone"):
attrib = zone.attrib
if attrib["territory"] == "001":
result[attrib["other"]] = attrib["type"]
HERE = Path(__file__).parent
DEST = HERE / "src" / "icalendar" / "timezone"
file = "windows_to_olson.py"
filepath = Path(DEST, file)
print(f"Writing {filepath}") # noqa: T201
with Path.open(filepath, "w") as f:
f.write(f'''"""
This module contains mappings from Windows timezone identifiers to
Olson timezone identifiers.
This file is automatically generated by generate_windows_to_olson_mapping.py.
Do not edit manually.
The data is taken from the Unicode Consortium [0] at commit
``{version}``, dated {version_date}.
The proposal and rationale for this mapping is also available at the
Unicode Consortium [1].
[0] https://github.com/unicode-org/cldr/blob/{version}/{CLDR_PATH}
[1] https://cldr.unicode.org/development/development-process/design-proposals/extended-windows-olson-zid-mapping
"""
version = {json.dumps(version)}
version_date = {json.dumps(version_date)}
''')
f.write("WINDOWS_TO_OLSON = ")
f.write(json.dumps(dict(result), indent=4, sort_keys=True))
f.write("\n")