fix(birth-sky): print the city for stored 「中国 · 省 · 市」 labels (BUG-1082)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
This commit is contained in:
Jesse_Chen
2026-09-29 00:51:42 +08:00
co-authored by Claude Opus 5.5
parent cfed06822f
commit 3d0f1cf6eb
3 changed files with 30 additions and 1 deletions
+4 -1
View File
@@ -26,6 +26,7 @@ const HAN = /[㐀-鿿]/;
/**
* City from a stored birth place label. Rules, most specific first:
*
* 0. A leading 「中国」 segment (how stored labels start) is dropped first.
* 1. Municipalities and SARs (`北京市 · 朝阳区`, `香港特别行政区`) → `北京`, `香港`.
* 2. Chinese labels `省 · 市 · 区` → the second segment when it ends in 「市」,
* without the 「市」 (`河北省 · 邯郸市 · 峰峰矿区` → `邯郸`). Prefectures that are
@@ -36,7 +37,9 @@ const HAN = /[㐀-鿿]/;
*/
export function birthSkyCity(label: string | null | undefined): string | null {
if (typeof label !== "string") return null;
const segments = label.split(SEPARATOR).map((segment) => segment.trim()).filter(Boolean);
const all = label.split(SEPARATOR).map((segment) => segment.trim()).filter(Boolean);
// Stored China labels lead with 「中国 · 」 (geoapify-location-service); the rules below start at the province (BUG-1082).
const segments = all[0] === "中国" ? all.slice(1) : all;
if (segments.length === 0) return null;
const [first, second, third] = segments;
if (CITY_PROVINCES[first]) return CITY_PROVINCES[first];
+11
View File
@@ -12,6 +12,17 @@ test("China 省 · 市 · 区 labels give the prefecture city without 「市」"
assert.equal(birthSkyCity("广西壮族自治区 · 桂林市 · 秀峰区"), "桂林");
});
// BUG-1082: stored labels are built as 「中国 · 省 · 市 · 区」 (geoapify-location-service.ts);
// the fixtures above lacked the prefix, so real Chinese birthplaces printed no city.
test("stored China labels lead with 「中国 · 」 and still give the city", () => {
assert.equal(birthSkyCity("中国 · 河北省 · 邯郸市 · 峰峰矿区"), "邯郸");
assert.equal(birthSkyCity("中国 · 浙江省 · 杭州市"), "杭州");
assert.equal(birthSkyCity("中国 · 北京市 · 北京市 · 朝阳区"), "北京");
assert.equal(birthSkyCity("中国 · 浙江省"), null);
assert.equal(birthSkyCity("中国"), null);
assert.equal(birthSkyCaption({ date: "1994-05-18", time: "07:40", placeLabel: "中国 · 浙江省 · 杭州市 · 西湖区" }), "1994年5月18日 07:40 · 杭州");
});
test("municipalities and SARs use their own name", () => {
assert.equal(birthSkyCity("北京市 · 朝阳区"), "北京");
assert.equal(birthSkyCity("上海市"), "上海");