Skip to content

Commit 764b215

Browse files
dr5hnclaude
andcommitted
fix(timezones): correct 72 city rows with foreign IANA zones (#1085 follow-up)
Sweeps the residual scope from #1085 — city rows whose timezone field points at a neighbouring country's zone instead of the correct local zone. VN 63 Asia/Bangkok -> Asia/Ho_Chi_Minh PS 6 Asia/Jerusalem -> Asia/Hebron (West Bank governates) UZ 2 Asia/Bishkek -> Asia/Tashkent (Fergana Region) ID 1 Asia/Ho_Chi_Minh -> Asia/Pontianak (Sambas, KB) TF/Tromelin (disputed admin) and FR/Nouméa (correct for state NC) excluded. Idempotent fix script under bin/scripts/fixes/. Summary in .github/fixes-docs/. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 4069a81 commit 764b215

6 files changed

Lines changed: 212 additions & 76 deletions

File tree

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Fix Summary: Foreign-zone city timezone cleanup (#1085 follow-up)
2+
3+
Closes the residual scope from #1085. The original issue called out a handful
4+
of countries (ES, RO) where city timezone fields pointed at the wrong IANA zone.
5+
Master is clean for those. This PR sweeps every remaining city row whose
6+
timezone field belongs to a neighbouring country.
7+
8+
## Scope
9+
10+
72 rows across 4 country files:
11+
12+
| File | Wrong zone | Correct zone | Rows |
13+
|------|------------|--------------|-----:|
14+
| `contributions/cities/VN.json` | `Asia/Bangkok` | `Asia/Ho_Chi_Minh` | 63 |
15+
| `contributions/cities/PS.json` | `Asia/Jerusalem` | `Asia/Hebron` | 6 |
16+
| `contributions/cities/UZ.json` | `Asia/Bishkek` | `Asia/Tashkent` | 2 |
17+
| `contributions/cities/ID.json` | `Asia/Ho_Chi_Minh` | `Asia/Pontianak` | 1 |
18+
19+
## Per-file rationale
20+
21+
- **VN (63 rows):** All 63 sit in Vietnamese provinces (state codes spanning
22+
northern, central, and southern VN). Vietnam observes ICT (UTC+7) in a single
23+
IANA zone: `Asia/Ho_Chi_Minh`. `Asia/Bangkok` is Thailand's zone — never
24+
correct for a Vietnamese city.
25+
26+
- **PS (6 rows):** All 6 sit in West Bank governates — Bethlehem (BTH),
27+
Hebron (HBN), Jerusalem governate (JEM), Salfit (SLT). The IANA mapping for
28+
the Palestinian territories is geographic: `Asia/Gaza` for Gaza Strip,
29+
`Asia/Hebron` for the West Bank. None of the 6 are in the Gaza Strip,
30+
so all map to `Asia/Hebron`. `Asia/Jerusalem` is Israel's zone.
31+
32+
- **UZ (2 rows):** Both are in Fergana Region (state_code `FA`), eastern
33+
Uzbekistan. Uzbekistan observes UZT (UTC+5) under `Asia/Tashkent` (the
34+
most populous IANA zone for the country) or `Asia/Samarkand`. `Asia/Bishkek`
35+
is Kyrgyzstan's zone — never correct for a Uzbek city.
36+
37+
- **ID (1 row):** Sambas (West Kalimantan, state_code `KB`) observes WIB
38+
(UTC+7) under `Asia/Pontianak`. `Asia/Ho_Chi_Minh` is Vietnam's zone.
39+
40+
## Out of scope
41+
42+
- **TF (Tromelin Island):** Currently tagged `Indian/Reunion`. Tromelin is
43+
administered by France as part of the Scattered Islands (TAAF) but is
44+
disputed with Mauritius. The current zone reflects de-facto administration —
45+
left untouched.
46+
- **FR (Nouméa, id 160039):** Tagged `Pacific/Noumea`. State_code is `NC`
47+
(New Caledonia, an FR overseas collectivity). This is correct, not a bug —
48+
excluded from the sweep.
49+
50+
## Verification
51+
52+
```
53+
$ python3 bin/scripts/fixes/foreign_timezone_fixes.py
54+
Total rows fixed: 72
55+
$ python3 bin/scripts/fixes/foreign_timezone_fixes.py
56+
Total rows fixed: 0 # idempotent
57+
```
58+
59+
After-counts: 0 VN rows tagged `Asia/Bangkok`, 0 PS rows tagged
60+
`Asia/Jerusalem`, 0 UZ rows tagged `Asia/Bishkek`, 0 ID rows tagged
61+
`Asia/Ho_Chi_Minh`.
62+
63+
Schema, cross-reference, coordinate-bounds, and duplicate validators all
64+
pass — no FK or geometry changes, only the `timezone` text field.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#!/usr/bin/env python3
2+
"""Fix 72 city rows tagged with foreign IANA timezones.
3+
4+
Issue #1085 close-out follow-up: VN/PS/UZ/ID rows whose timezone field
5+
points to a neighbouring country's zone instead of the correct local zone.
6+
7+
Idempotent. Safe to re-run.
8+
"""
9+
10+
import json
11+
import sys
12+
from pathlib import Path
13+
14+
ROOT = Path(__file__).resolve().parents[3] / "contributions" / "cities"
15+
16+
PLAN = [
17+
{
18+
"file": "VN.json",
19+
"rule": "Asia/Bangkok -> Asia/Ho_Chi_Minh",
20+
"match": lambda r: r.get("timezone") == "Asia/Bangkok",
21+
"set_tz": "Asia/Ho_Chi_Minh",
22+
},
23+
{
24+
"file": "PS.json",
25+
"rule": "Asia/Jerusalem -> Asia/Hebron (all 6 rows are West Bank governates)",
26+
"match": lambda r: r.get("timezone") == "Asia/Jerusalem",
27+
"set_tz": "Asia/Hebron",
28+
},
29+
{
30+
"file": "UZ.json",
31+
"rule": "Asia/Bishkek -> Asia/Tashkent (Fergana Region rows)",
32+
"match": lambda r: r.get("timezone") == "Asia/Bishkek",
33+
"set_tz": "Asia/Tashkent",
34+
},
35+
{
36+
"file": "ID.json",
37+
"rule": "Asia/Ho_Chi_Minh -> Asia/Pontianak (Sambas, West Kalimantan)",
38+
"match": lambda r: r.get("timezone") == "Asia/Ho_Chi_Minh",
39+
"set_tz": "Asia/Pontianak",
40+
},
41+
]
42+
43+
44+
def apply(plan):
45+
path = ROOT / plan["file"]
46+
if not path.exists():
47+
sys.exit(f"missing: {path}")
48+
rows = json.loads(path.read_text())
49+
changed = 0
50+
for r in rows:
51+
if plan["match"](r) and r.get("timezone") != plan["set_tz"]:
52+
r["timezone"] = plan["set_tz"]
53+
changed += 1
54+
path.write_text(json.dumps(rows, indent=2, ensure_ascii=False) + "\n")
55+
return changed, len(rows)
56+
57+
58+
def main():
59+
print("Foreign-timezone cleanup (issue #1085 follow-up)")
60+
print("=" * 60)
61+
total = 0
62+
for plan in PLAN:
63+
changed, n = apply(plan)
64+
total += changed
65+
print(f" {plan['file']:>10} {plan['rule']}")
66+
print(f" {'':>10} changed {changed} of {n} rows")
67+
print("=" * 60)
68+
print(f"Total rows fixed: {total}")
69+
70+
71+
if __name__ == "__main__":
72+
main()

contributions/cities/ID.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32321,7 +32321,7 @@
3232132321
"longitude": "109.35000000",
3232232322
"native": "Sambas",
3232332323
"population": 57295,
32324-
"timezone": "Asia/Ho_Chi_Minh",
32324+
"timezone": "Asia/Pontianak",
3232532325
"translations": {
3232632326
"br": "Sambas",
3232732327
"ko": "삼바스",
@@ -32758,4 +32758,4 @@
3275832758
"flag": 1,
3275932759
"wikiDataId": "Q10116"
3276032760
}
32761-
]
32761+
]

contributions/cities/PS.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"longitude": "35.11743230",
1414
"native": "بتير",
1515
"population": 56746,
16-
"timezone": "Asia/Jerusalem",
16+
"timezone": "Asia/Hebron",
1717
"translations": {
1818
"br": "Battir",
1919
"ko": "바티르",
@@ -300,7 +300,7 @@
300300
"longitude": "35.15014530",
301301
"native": "الخضر",
302302
"population": 10088,
303-
"timezone": "Asia/Jerusalem",
303+
"timezone": "Asia/Hebron",
304304
"translations": {
305305
"br": "al-Khader",
306306
"ko": "알-카데르",
@@ -341,7 +341,7 @@
341341
"longitude": "35.09976230",
342342
"native": "نحالين",
343343
"population": 1021,
344-
"timezone": "Asia/Jerusalem",
344+
"timezone": "Asia/Hebron",
345345
"translations": {
346346
"br": "Nahalin",
347347
"ko": "나할린",
@@ -1202,7 +1202,7 @@
12021202
"longitude": "35.12317630",
12031203
"native": "سعير",
12041204
"population": 3151,
1205-
"timezone": "Asia/Jerusalem",
1205+
"timezone": "Asia/Hebron",
12061206
"translations": {
12071207
"br": "Sa'ir",
12081208
"ko": "사이르",
@@ -2391,7 +2391,7 @@
23912391
"longitude": "35.24263130",
23922392
"native": "حزما",
23932393
"population": 8194,
2394-
"timezone": "Asia/Jerusalem",
2394+
"timezone": "Asia/Hebron",
23952395
"translations": {
23962396
"br": "Hizma",
23972397
"ko": "히즈마",
@@ -4605,7 +4605,7 @@
46054605
"longitude": "35.06050810",
46064606
"native": "كفر الديك",
46074607
"population": 4280,
4608-
"timezone": "Asia/Jerusalem",
4608+
"timezone": "Asia/Hebron",
46094609
"translations": {
46104610
"br": "Kafr ad-Dik",
46114611
"ko": "카프르 아드딕",
@@ -5411,4 +5411,4 @@
54115411
"flag": 1,
54125412
"wikiDataId": "Q985531"
54135413
}
5414-
]
5414+
]

contributions/cities/UZ.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3908,7 +3908,7 @@
39083908
"longitude": "71.98026000",
39093909
"native": "Quvasoy",
39103910
"population": 96900,
3911-
"timezone": "Asia/Bishkek",
3911+
"timezone": "Asia/Tashkent",
39123912
"translations": {
39133913
"br": "Quvasoy",
39143914
"ko": "쿠바소이",
@@ -4359,7 +4359,7 @@
43594359
"longitude": "71.80512000",
43604360
"native": "Shohimardon",
43614361
"population": 5100,
4362-
"timezone": "Asia/Bishkek",
4362+
"timezone": "Asia/Tashkent",
43634363
"translations": {
43644364
"br": "Shohimardon",
43654365
"ko": "쇼히마르돈",
@@ -5534,4 +5534,4 @@
55345534
"flag": 1,
55355535
"wikiDataId": "Q32059593"
55365536
}
5537-
]
5537+
]

0 commit comments

Comments
 (0)