多语言开发:Locale 语言代码规范与完整列表(Java / C++ / C# / JavaScript)
语言选择列表看似简单,实际很容易在多个技术栈之间出现分叉:同一种语言用了不同代码、语言名大小写不一致,或者把标准库生成的名称直接当成产品文案。
本文给出一套可落地的跨语言约定,并整理了一份包含 79 项的参考目录。它适用于 Java、C++、C#、JavaScript/TypeScript 等客户端、服务端和工具程序。核心目标是:内部代码稳定、对外接口符合标准、UI 显示一致。
1. 如何理解语言代码
本文示例中的内部语言代码采用:
language_REGION
例如:
en_US:英语 + 美国pt_BR:葡萄牙语 + 巴西zh_HK:中文 + 香港
约定如下:
language使用小写语言子标签,主要依据 IANA Language Subtag Registry。REGION使用大写地区子标签,通常对应 ISO 3166-1 两位地区代码,并在 IANA 注册表中登记。- 下划线
_可以作为应用内部的稳定格式;严格的 BCP 47 写法使用连字符,例如fil-PH。内部存储与外部接口应明确分层,不要在同一数据域中混用两种格式。 - 语言代码用于程序识别,显示名称用于 UI 展示,两者必须分别按各自规则维护。
2. 四个容易混淆的代码
| 原代码 | 建议写法 | 调整依据 |
|---|---|---|
iw_IL |
he_IL |
iw 是希伯来语的旧代码,IANA 的首选值是 he。 |
in_ID |
id_ID |
in 是印度尼西亚语的旧代码,IANA 的首选值是 id。 |
tl_PH |
fil_PH |
tl 是仍然有效的 Tagalog 代码,并非废弃代码;当名称和产品语义是 Filipino 时才应使用 fil。 |
my_ZG |
my_MM |
如果原意是“缅甸语 + 缅甸地区”,应使用已注册地区代码 MM;ZG 不是地区子标签。若 ZG 原本指 Zawgyi 编码,则应把编码方式建模为独立字段,不能用地区位代替。 |
如果现有数据没有兼容负担,建议直接使用建议写法,不再保留旧代码别名。如果已经存在历史配置、数据库记录或外部调用方,则应先完成数据迁移,并在明确的过渡期内提供兼容映射。
需要注意,第三方翻译 API 可能仍要求 tl 等自定义参数。这类值属于供应商接口映射,不应反向替代应用内部使用的 fil_PH。
3. 显示名称规则
每项语言包含两个显示名称:
- 中文名称:供中文界面或管理场景使用。
- 本地名称:使用该语言自身的文字和常见自称形式。
统一规则:
- 以 Unicode CLDR 的现代语言名称和地区名称为主要参考。
- 同一语言存在多个地区版本时,在名称中明确地区,例如
English (United States)、Français (Canada)。 - 独立出现在语言选择列表中的名称,统一采用适合 UI 标签的首字母形式,例如
Magyar、Italiano (Italia)。 - 语言学上,匈牙利语
magyar、意大利语lingua italiana在普通句子中使用小写可以成立;但产品语言列表需要一致、明确且便于区分地区版本,因此本文采用规范表中的 UI 写法。 - 不把英文翻译冒充本地名称,也不混用语言名、国名和形容词。
- 乌兹别克语在本文参考目录中使用西里尔字母名称
Ўзбекча;如果产品采用拉丁字母版本,应在自己的语言资源策略中明确选择,避免两种写法随机出现。
4. 参考语言目录
| 代码 | 中文名称 | 本地名称 |
|---|---|---|
zh_CN |
简体中文 | 简体中文 |
zh_TW |
繁体中文(台湾) | 繁體中文(台灣) |
zh_HK |
繁体中文(香港) | 繁體中文(香港) |
nl_NL |
荷兰语 | Nederlands (Nederland) |
nl_BE |
荷兰语(比利时) | Nederlands (België) |
en_US |
英语(美国) | English (United States) |
en_AU |
英语(澳大利亚) | English (Australia) |
en_CA |
英语(加拿大) | English (Canada) |
en_IN |
英语(印度) | English (India) |
en_IE |
英语(爱尔兰) | English (Ireland) |
en_NZ |
英语(新西兰) | English (New Zealand) |
en_SG |
英语(新加坡) | English (Singapore) |
en_ZA |
英语(南非) | English (South Africa) |
en_GB |
英语(英国) | English (United Kingdom) |
fr_FR |
法语 | Français (France) |
fr_BE |
法语(比利时) | Français (Belgique) |
fr_CA |
法语(加拿大) | Français (Canada) |
fr_CH |
法语(瑞士) | Français (Suisse) |
de_DE |
德语 | Deutsch (Deutschland) |
de_LI |
德语(列支敦斯登) | Deutsch (Liechtenstein) |
de_AT |
德语(奥地利) | Deutsch (Österreich) |
de_CH |
德语(瑞士) | Deutsch (Schweiz) |
it_IT |
意大利语 | Italiano (Italia) |
it_CH |
意大利语(瑞士) | Italiano (Svizzera) |
pt_BR |
葡萄牙语(巴西) | Português (Brasil) |
pt_PT |
葡萄牙语 | Português (Portugal) |
es_ES |
西班牙语 | Español (España) |
es_US |
西班牙语(美国) | Español (Estados Unidos) |
bn_BD |
孟加拉语 | বাংলা (বাংলাদেশ) |
bn_IN |
孟加拉语(印度) | বাংলা (ভারত) |
hr_HR |
克罗地亚语 | Hrvatski |
cs_CZ |
捷克语 | Čeština |
da_DK |
丹麦语 | Dansk |
el_GR |
希腊语 | Ελληνικά |
he_IL |
希伯来语(以色列) | עברית |
hi_IN |
印地语 | हिन्दी |
hu_HU |
匈牙利语 | Magyar |
id_ID |
印度尼西亚语 | Bahasa Indonesia |
ja_JP |
日语 | 日本語 |
ko_KR |
韩语 | 한국어 |
ms_MY |
马来语 | Melayu |
fa_IR |
波斯语 | فارسی |
pl_PL |
波兰语 | Polski |
ro_RO |
罗马尼亚语 | Română |
ru_RU |
俄语 | Русский |
sr_RS |
塞尔维亚语 | Српски |
sv_SE |
瑞典语 | Svenska |
th_TH |
泰语 | ไทย |
tr_TR |
土耳其语 | Türkçe |
ur_PK |
乌尔都语 | اردو |
vi_VN |
越南语 | Tiếng Việt |
ca_ES |
加泰罗尼亚语(西班牙) | Català |
lv_LV |
拉脱维亚语 | Latviešu |
lt_LT |
立陶宛语 | Lietuvių |
nb_NO |
书面挪威语 | Norsk bokmål |
sk_SK |
斯洛伐克语 | Slovenčina |
sl_SI |
斯洛文尼亚语 | Slovenščina |
bg_BG |
保加利亚语 | Български |
uk_UA |
乌克兰语 | Українська |
fil_PH |
菲律宾语 | Filipino |
fi_FI |
芬兰语 | Suomi |
af_ZA |
南非荷兰语 | Afrikaans |
rm_CH |
罗曼什语(瑞士) | Rumantsch |
km_KH |
高棉语 | ខ្មែរ |
my_MM |
缅甸语 | မြန်မာ |
am_ET |
阿姆哈拉语(埃塞俄比亚) | አማርኛ |
be_BY |
白俄罗斯语 | Беларуская |
et_EE |
爱沙尼亚语 | Eesti |
sw_TZ |
斯瓦希里语(坦桑尼亚) | Kiswahili |
zu_ZA |
祖鲁语(南非) | IsiZulu |
az_AZ |
阿塞拜疆语 | Azərbaycan |
hy_AM |
亚美尼亚语(亚美尼亚) | Հայերեն |
ka_GE |
格鲁吉亚语(格鲁吉亚) | ქართული |
lo_LA |
老挝语(老挝) | ລາວ |
mn_MN |
蒙古语 | Монгол |
ne_NP |
尼泊尔语 | नेपाली |
kk_KZ |
哈萨克语 | Қазақ тілі |
si_LK |
僧伽罗语(斯里兰卡) | සිංහල |
uz_UZ |
乌兹别克语 | Ўзбекча |
5. 可直接复制的完整代码
下面的 JSON、Java、C++、C# 和 JavaScript/TypeScript 示例都包含第 4 节的完整 79 项,字段、内容和顺序保持一致。读者只需选择自己的技术栈并整段复制,不需要再从 Markdown 表格逐条转换。
所有实现都遵守同一数据契约:
| 字段 | 含义 | 示例 |
|---|---|---|
code |
应用内部稳定代码 | fil_PH |
zhName |
中文显示名称 | 菲律宾语 |
nativeName |
本地语言显示名称 | Filipino |
共同边界规则:
- 配置文件、数据库、文件名和系统间通信保存
language_REGION,例如fil_PH。 - 调用要求 BCP 47 的标准库或 Web API 时,在调用边界将
_转为-,例如fil_PH → fil-PH。 - 不要把整个代码统一转为大写或小写;语言部分小写,地区部分大写。
- UI 直接使用目录中的
zhName或nativeName,不要依赖不同版本的操作系统、JDK、浏览器或 .NET 动态生成产品名称。 - 第三方翻译 API 的语言参数维护独立映射,不要反向污染应用内部代码。
- 源码、JSON、数据库和网络传输统一使用 Unicode;新数据文件优先使用 UTF-8。
5.1 JSON
可将下面的内容直接保存为 language-catalog.json,作为不同技术栈共享的真值源:
[
{ "code": "zh_CN", "zhName": "简体中文", "nativeName": "简体中文" },
{ "code": "zh_TW", "zhName": "繁体中文(台湾)", "nativeName": "繁體中文(台灣)" },
{ "code": "zh_HK", "zhName": "繁体中文(香港)", "nativeName": "繁體中文(香港)" },
{ "code": "nl_NL", "zhName": "荷兰语", "nativeName": "Nederlands (Nederland)" },
{ "code": "nl_BE", "zhName": "荷兰语(比利时)", "nativeName": "Nederlands (België)" },
{ "code": "en_US", "zhName": "英语(美国)", "nativeName": "English (United States)" },
{ "code": "en_AU", "zhName": "英语(澳大利亚)", "nativeName": "English (Australia)" },
{ "code": "en_CA", "zhName": "英语(加拿大)", "nativeName": "English (Canada)" },
{ "code": "en_IN", "zhName": "英语(印度)", "nativeName": "English (India)" },
{ "code": "en_IE", "zhName": "英语(爱尔兰)", "nativeName": "English (Ireland)" },
{ "code": "en_NZ", "zhName": "英语(新西兰)", "nativeName": "English (New Zealand)" },
{ "code": "en_SG", "zhName": "英语(新加坡)", "nativeName": "English (Singapore)" },
{ "code": "en_ZA", "zhName": "英语(南非)", "nativeName": "English (South Africa)" },
{ "code": "en_GB", "zhName": "英语(英国)", "nativeName": "English (United Kingdom)" },
{ "code": "fr_FR", "zhName": "法语", "nativeName": "Français (France)" },
{ "code": "fr_BE", "zhName": "法语(比利时)", "nativeName": "Français (Belgique)" },
{ "code": "fr_CA", "zhName": "法语(加拿大)", "nativeName": "Français (Canada)" },
{ "code": "fr_CH", "zhName": "法语(瑞士)", "nativeName": "Français (Suisse)" },
{ "code": "de_DE", "zhName": "德语", "nativeName": "Deutsch (Deutschland)" },
{ "code": "de_LI", "zhName": "德语(列支敦斯登)", "nativeName": "Deutsch (Liechtenstein)" },
{ "code": "de_AT", "zhName": "德语(奥地利)", "nativeName": "Deutsch (Österreich)" },
{ "code": "de_CH", "zhName": "德语(瑞士)", "nativeName": "Deutsch (Schweiz)" },
{ "code": "it_IT", "zhName": "意大利语", "nativeName": "Italiano (Italia)" },
{ "code": "it_CH", "zhName": "意大利语(瑞士)", "nativeName": "Italiano (Svizzera)" },
{ "code": "pt_BR", "zhName": "葡萄牙语(巴西)", "nativeName": "Português (Brasil)" },
{ "code": "pt_PT", "zhName": "葡萄牙语", "nativeName": "Português (Portugal)" },
{ "code": "es_ES", "zhName": "西班牙语", "nativeName": "Español (España)" },
{ "code": "es_US", "zhName": "西班牙语(美国)", "nativeName": "Español (Estados Unidos)" },
{ "code": "bn_BD", "zhName": "孟加拉语", "nativeName": "বাংলা (বাংলাদেশ)" },
{ "code": "bn_IN", "zhName": "孟加拉语(印度)", "nativeName": "বাংলা (ভারত)" },
{ "code": "hr_HR", "zhName": "克罗地亚语", "nativeName": "Hrvatski" },
{ "code": "cs_CZ", "zhName": "捷克语", "nativeName": "Čeština" },
{ "code": "da_DK", "zhName": "丹麦语", "nativeName": "Dansk" },
{ "code": "el_GR", "zhName": "希腊语", "nativeName": "Ελληνικά" },
{ "code": "he_IL", "zhName": "希伯来语(以色列)", "nativeName": "עברית" },
{ "code": "hi_IN", "zhName": "印地语", "nativeName": "हिन्दी" },
{ "code": "hu_HU", "zhName": "匈牙利语", "nativeName": "Magyar" },
{ "code": "id_ID", "zhName": "印度尼西亚语", "nativeName": "Bahasa Indonesia" },
{ "code": "ja_JP", "zhName": "日语", "nativeName": "日本語" },
{ "code": "ko_KR", "zhName": "韩语", "nativeName": "한국어" },
{ "code": "ms_MY", "zhName": "马来语", "nativeName": "Melayu" },
{ "code": "fa_IR", "zhName": "波斯语", "nativeName": "فارسی" },
{ "code": "pl_PL", "zhName": "波兰语", "nativeName": "Polski" },
{ "code": "ro_RO", "zhName": "罗马尼亚语", "nativeName": "Română" },
{ "code": "ru_RU", "zhName": "俄语", "nativeName": "Русский" },
{ "code": "sr_RS", "zhName": "塞尔维亚语", "nativeName": "Српски" },
{ "code": "sv_SE", "zhName": "瑞典语", "nativeName": "Svenska" },
{ "code": "th_TH", "zhName": "泰语", "nativeName": "ไทย" },
{ "code": "tr_TR", "zhName": "土耳其语", "nativeName": "Türkçe" },
{ "code": "ur_PK", "zhName": "乌尔都语", "nativeName": "اردو" },
{ "code": "vi_VN", "zhName": "越南语", "nativeName": "Tiếng Việt" },
{ "code": "ca_ES", "zhName": "加泰罗尼亚语(西班牙)", "nativeName": "Català" },
{ "code": "lv_LV", "zhName": "拉脱维亚语", "nativeName": "Latviešu" },
{ "code": "lt_LT", "zhName": "立陶宛语", "nativeName": "Lietuvių" },
{ "code": "nb_NO", "zhName": "书面挪威语", "nativeName": "Norsk bokmål" },
{ "code": "sk_SK", "zhName": "斯洛伐克语", "nativeName": "Slovenčina" },
{ "code": "sl_SI", "zhName": "斯洛文尼亚语", "nativeName": "Slovenščina" },
{ "code": "bg_BG", "zhName": "保加利亚语", "nativeName": "Български" },
{ "code": "uk_UA", "zhName": "乌克兰语", "nativeName": "Українська" },
{ "code": "fil_PH", "zhName": "菲律宾语", "nativeName": "Filipino" },
{ "code": "fi_FI", "zhName": "芬兰语", "nativeName": "Suomi" },
{ "code": "af_ZA", "zhName": "南非荷兰语", "nativeName": "Afrikaans" },
{ "code": "rm_CH", "zhName": "罗曼什语(瑞士)", "nativeName": "Rumantsch" },
{ "code": "km_KH", "zhName": "高棉语", "nativeName": "ខ្មែរ" },
{ "code": "my_MM", "zhName": "缅甸语", "nativeName": "မြန်မာ" },
{ "code": "am_ET", "zhName": "阿姆哈拉语(埃塞俄比亚)", "nativeName": "አማርኛ" },
{ "code": "be_BY", "zhName": "白俄罗斯语", "nativeName": "Беларуская" },
{ "code": "et_EE", "zhName": "爱沙尼亚语", "nativeName": "Eesti" },
{ "code": "sw_TZ", "zhName": "斯瓦希里语(坦桑尼亚)", "nativeName": "Kiswahili" },
{ "code": "zu_ZA", "zhName": "祖鲁语(南非)", "nativeName": "IsiZulu" },
{ "code": "az_AZ", "zhName": "阿塞拜疆语", "nativeName": "Azərbaycan" },
{ "code": "hy_AM", "zhName": "亚美尼亚语(亚美尼亚)", "nativeName": "Հայերեն" },
{ "code": "ka_GE", "zhName": "格鲁吉亚语(格鲁吉亚)", "nativeName": "ქართული" },
{ "code": "lo_LA", "zhName": "老挝语(老挝)", "nativeName": "ລາວ" },
{ "code": "mn_MN", "zhName": "蒙古语", "nativeName": "Монгол" },
{ "code": "ne_NP", "zhName": "尼泊尔语", "nativeName": "नेपाली" },
{ "code": "kk_KZ", "zhName": "哈萨克语", "nativeName": "Қазақ тілі" },
{ "code": "si_LK", "zhName": "僧伽罗语(斯里兰卡)", "nativeName": "සිංහල" },
{ "code": "uz_UZ", "zhName": "乌兹别克语", "nativeName": "Ўзбекча" }
]
5.2 Java(Java 8+)
下面是一个完整、可独立保存的 Java 类,包含不可变语言列表、代码查找和 BCP 47 转换:
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
public final class LanguageCatalog {
public static final class LanguageOption {
public final String code;
public final String zhName;
public final String nativeName;
public LanguageOption(String code, String zhName, String nativeName) {
this.code = code;
this.zhName = zhName;
this.nativeName = nativeName;
}
public String toLanguageTag() {
return code.replace('_', '-');
}
public Locale toLocale() {
return Locale.forLanguageTag(toLanguageTag());
}
public String displayName(boolean chineseUi) {
return chineseUi ? zhName : nativeName;
}
}
public static final List<LanguageOption> ALL =
Collections.unmodifiableList(Arrays.asList(
new LanguageOption("zh_CN", "简体中文", "简体中文"),
new LanguageOption("zh_TW", "繁体中文(台湾)", "繁體中文(台灣)"),
new LanguageOption("zh_HK", "繁体中文(香港)", "繁體中文(香港)"),
new LanguageOption("nl_NL", "荷兰语", "Nederlands (Nederland)"),
new LanguageOption("nl_BE", "荷兰语(比利时)", "Nederlands (België)"),
new LanguageOption("en_US", "英语(美国)", "English (United States)"),
new LanguageOption("en_AU", "英语(澳大利亚)", "English (Australia)"),
new LanguageOption("en_CA", "英语(加拿大)", "English (Canada)"),
new LanguageOption("en_IN", "英语(印度)", "English (India)"),
new LanguageOption("en_IE", "英语(爱尔兰)", "English (Ireland)"),
new LanguageOption("en_NZ", "英语(新西兰)", "English (New Zealand)"),
new LanguageOption("en_SG", "英语(新加坡)", "English (Singapore)"),
new LanguageOption("en_ZA", "英语(南非)", "English (South Africa)"),
new LanguageOption("en_GB", "英语(英国)", "English (United Kingdom)"),
new LanguageOption("fr_FR", "法语", "Français (France)"),
new LanguageOption("fr_BE", "法语(比利时)", "Français (Belgique)"),
new LanguageOption("fr_CA", "法语(加拿大)", "Français (Canada)"),
new LanguageOption("fr_CH", "法语(瑞士)", "Français (Suisse)"),
new LanguageOption("de_DE", "德语", "Deutsch (Deutschland)"),
new LanguageOption("de_LI", "德语(列支敦斯登)", "Deutsch (Liechtenstein)"),
new LanguageOption("de_AT", "德语(奥地利)", "Deutsch (Österreich)"),
new LanguageOption("de_CH", "德语(瑞士)", "Deutsch (Schweiz)"),
new LanguageOption("it_IT", "意大利语", "Italiano (Italia)"),
new LanguageOption("it_CH", "意大利语(瑞士)", "Italiano (Svizzera)"),
new LanguageOption("pt_BR", "葡萄牙语(巴西)", "Português (Brasil)"),
new LanguageOption("pt_PT", "葡萄牙语", "Português (Portugal)"),
new LanguageOption("es_ES", "西班牙语", "Español (España)"),
new LanguageOption("es_US", "西班牙语(美国)", "Español (Estados Unidos)"),
new LanguageOption("bn_BD", "孟加拉语", "বাংলা (বাংলাদেশ)"),
new LanguageOption("bn_IN", "孟加拉语(印度)", "বাংলা (ভারত)"),
new LanguageOption("hr_HR", "克罗地亚语", "Hrvatski"),
new LanguageOption("cs_CZ", "捷克语", "Čeština"),
new LanguageOption("da_DK", "丹麦语", "Dansk"),
new LanguageOption("el_GR", "希腊语", "Ελληνικά"),
new LanguageOption("he_IL", "希伯来语(以色列)", "עברית"),
new LanguageOption("hi_IN", "印地语", "हिन्दी"),
new LanguageOption("hu_HU", "匈牙利语", "Magyar"),
new LanguageOption("id_ID", "印度尼西亚语", "Bahasa Indonesia"),
new LanguageOption("ja_JP", "日语", "日本語"),
new LanguageOption("ko_KR", "韩语", "한국어"),
new LanguageOption("ms_MY", "马来语", "Melayu"),
new LanguageOption("fa_IR", "波斯语", "فارسی"),
new LanguageOption("pl_PL", "波兰语", "Polski"),
new LanguageOption("ro_RO", "罗马尼亚语", "Română"),
new LanguageOption("ru_RU", "俄语", "Русский"),
new LanguageOption("sr_RS", "塞尔维亚语", "Српски"),
new LanguageOption("sv_SE", "瑞典语", "Svenska"),
new LanguageOption("th_TH", "泰语", "ไทย"),
new LanguageOption("tr_TR", "土耳其语", "Türkçe"),
new LanguageOption("ur_PK", "乌尔都语", "اردو"),
new LanguageOption("vi_VN", "越南语", "Tiếng Việt"),
new LanguageOption("ca_ES", "加泰罗尼亚语(西班牙)", "Català"),
new LanguageOption("lv_LV", "拉脱维亚语", "Latviešu"),
new LanguageOption("lt_LT", "立陶宛语", "Lietuvių"),
new LanguageOption("nb_NO", "书面挪威语", "Norsk bokmål"),
new LanguageOption("sk_SK", "斯洛伐克语", "Slovenčina"),
new LanguageOption("sl_SI", "斯洛文尼亚语", "Slovenščina"),
new LanguageOption("bg_BG", "保加利亚语", "Български"),
new LanguageOption("uk_UA", "乌克兰语", "Українська"),
new LanguageOption("fil_PH", "菲律宾语", "Filipino"),
new LanguageOption("fi_FI", "芬兰语", "Suomi"),
new LanguageOption("af_ZA", "南非荷兰语", "Afrikaans"),
new LanguageOption("rm_CH", "罗曼什语(瑞士)", "Rumantsch"),
new LanguageOption("km_KH", "高棉语", "ខ្មែរ"),
new LanguageOption("my_MM", "缅甸语", "မြန်မာ"),
new LanguageOption("am_ET", "阿姆哈拉语(埃塞俄比亚)", "አማርኛ"),
new LanguageOption("be_BY", "白俄罗斯语", "Беларуская"),
new LanguageOption("et_EE", "爱沙尼亚语", "Eesti"),
new LanguageOption("sw_TZ", "斯瓦希里语(坦桑尼亚)", "Kiswahili"),
new LanguageOption("zu_ZA", "祖鲁语(南非)", "IsiZulu"),
new LanguageOption("az_AZ", "阿塞拜疆语", "Azərbaycan"),
new LanguageOption("hy_AM", "亚美尼亚语(亚美尼亚)", "Հայերեն"),
new LanguageOption("ka_GE", "格鲁吉亚语(格鲁吉亚)", "ქართული"),
new LanguageOption("lo_LA", "老挝语(老挝)", "ລາວ"),
new LanguageOption("mn_MN", "蒙古语", "Монгол"),
new LanguageOption("ne_NP", "尼泊尔语", "नेपाली"),
new LanguageOption("kk_KZ", "哈萨克语", "Қазақ тілі"),
new LanguageOption("si_LK", "僧伽罗语(斯里兰卡)", "සිංහල"),
new LanguageOption("uz_UZ", "乌兹别克语", "Ўзбекча")
));
public static LanguageOption findByCode(String code) {
for (LanguageOption option : ALL) {
if (option.code.equals(code)) {
return option;
}
}
return null;
}
private LanguageCatalog() {
}
}
调用示例:
LanguageCatalog.LanguageOption option =
LanguageCatalog.findByCode("fil_PH");
if (option != null) {
Locale locale = option.toLocale(); // fil-PH
String uiText = option.displayName(false); // Filipino
}
5.3 C++(C++11+)
下面的版本使用宽字符串保存显示名称,适合 Windows/MSVC,也避开了 C++20 中 u8"..." 变为 char8_t 后不能直接赋给 std::string 的差异:
#include <algorithm>
#include <cstddef>
#include <string>
struct LanguageOption {
const char* code;
const wchar_t* zhName;
const wchar_t* nativeName;
};
static const LanguageOption kLanguages[] = {
{ "zh_CN", L"简体中文", L"简体中文" },
{ "zh_TW", L"繁体中文(台湾)", L"繁體中文(台灣)" },
{ "zh_HK", L"繁体中文(香港)", L"繁體中文(香港)" },
{ "nl_NL", L"荷兰语", L"Nederlands (Nederland)" },
{ "nl_BE", L"荷兰语(比利时)", L"Nederlands (België)" },
{ "en_US", L"英语(美国)", L"English (United States)" },
{ "en_AU", L"英语(澳大利亚)", L"English (Australia)" },
{ "en_CA", L"英语(加拿大)", L"English (Canada)" },
{ "en_IN", L"英语(印度)", L"English (India)" },
{ "en_IE", L"英语(爱尔兰)", L"English (Ireland)" },
{ "en_NZ", L"英语(新西兰)", L"English (New Zealand)" },
{ "en_SG", L"英语(新加坡)", L"English (Singapore)" },
{ "en_ZA", L"英语(南非)", L"English (South Africa)" },
{ "en_GB", L"英语(英国)", L"English (United Kingdom)" },
{ "fr_FR", L"法语", L"Français (France)" },
{ "fr_BE", L"法语(比利时)", L"Français (Belgique)" },
{ "fr_CA", L"法语(加拿大)", L"Français (Canada)" },
{ "fr_CH", L"法语(瑞士)", L"Français (Suisse)" },
{ "de_DE", L"德语", L"Deutsch (Deutschland)" },
{ "de_LI", L"德语(列支敦斯登)", L"Deutsch (Liechtenstein)" },
{ "de_AT", L"德语(奥地利)", L"Deutsch (Österreich)" },
{ "de_CH", L"德语(瑞士)", L"Deutsch (Schweiz)" },
{ "it_IT", L"意大利语", L"Italiano (Italia)" },
{ "it_CH", L"意大利语(瑞士)", L"Italiano (Svizzera)" },
{ "pt_BR", L"葡萄牙语(巴西)", L"Português (Brasil)" },
{ "pt_PT", L"葡萄牙语", L"Português (Portugal)" },
{ "es_ES", L"西班牙语", L"Español (España)" },
{ "es_US", L"西班牙语(美国)", L"Español (Estados Unidos)" },
{ "bn_BD", L"孟加拉语", L"বাংলা (বাংলাদেশ)" },
{ "bn_IN", L"孟加拉语(印度)", L"বাংলা (ভারত)" },
{ "hr_HR", L"克罗地亚语", L"Hrvatski" },
{ "cs_CZ", L"捷克语", L"Čeština" },
{ "da_DK", L"丹麦语", L"Dansk" },
{ "el_GR", L"希腊语", L"Ελληνικά" },
{ "he_IL", L"希伯来语(以色列)", L"עברית" },
{ "hi_IN", L"印地语", L"हिन्दी" },
{ "hu_HU", L"匈牙利语", L"Magyar" },
{ "id_ID", L"印度尼西亚语", L"Bahasa Indonesia" },
{ "ja_JP", L"日语", L"日本語" },
{ "ko_KR", L"韩语", L"한국어" },
{ "ms_MY", L"马来语", L"Melayu" },
{ "fa_IR", L"波斯语", L"فارسی" },
{ "pl_PL", L"波兰语", L"Polski" },
{ "ro_RO", L"罗马尼亚语", L"Română" },
{ "ru_RU", L"俄语", L"Русский" },
{ "sr_RS", L"塞尔维亚语", L"Српски" },
{ "sv_SE", L"瑞典语", L"Svenska" },
{ "th_TH", L"泰语", L"ไทย" },
{ "tr_TR", L"土耳其语", L"Türkçe" },
{ "ur_PK", L"乌尔都语", L"اردو" },
{ "vi_VN", L"越南语", L"Tiếng Việt" },
{ "ca_ES", L"加泰罗尼亚语(西班牙)", L"Català" },
{ "lv_LV", L"拉脱维亚语", L"Latviešu" },
{ "lt_LT", L"立陶宛语", L"Lietuvių" },
{ "nb_NO", L"书面挪威语", L"Norsk bokmål" },
{ "sk_SK", L"斯洛伐克语", L"Slovenčina" },
{ "sl_SI", L"斯洛文尼亚语", L"Slovenščina" },
{ "bg_BG", L"保加利亚语", L"Български" },
{ "uk_UA", L"乌克兰语", L"Українська" },
{ "fil_PH", L"菲律宾语", L"Filipino" },
{ "fi_FI", L"芬兰语", L"Suomi" },
{ "af_ZA", L"南非荷兰语", L"Afrikaans" },
{ "rm_CH", L"罗曼什语(瑞士)", L"Rumantsch" },
{ "km_KH", L"高棉语", L"ខ្មែរ" },
{ "my_MM", L"缅甸语", L"မြန်မာ" },
{ "am_ET", L"阿姆哈拉语(埃塞俄比亚)", L"አማርኛ" },
{ "be_BY", L"白俄罗斯语", L"Беларуская" },
{ "et_EE", L"爱沙尼亚语", L"Eesti" },
{ "sw_TZ", L"斯瓦希里语(坦桑尼亚)", L"Kiswahili" },
{ "zu_ZA", L"祖鲁语(南非)", L"IsiZulu" },
{ "az_AZ", L"阿塞拜疆语", L"Azərbaycan" },
{ "hy_AM", L"亚美尼亚语(亚美尼亚)", L"Հայերեն" },
{ "ka_GE", L"格鲁吉亚语(格鲁吉亚)", L"ქართული" },
{ "lo_LA", L"老挝语(老挝)", L"ລາວ" },
{ "mn_MN", L"蒙古语", L"Монгол" },
{ "ne_NP", L"尼泊尔语", L"नेपाली" },
{ "kk_KZ", L"哈萨克语", L"Қазақ тілі" },
{ "si_LK", L"僧伽罗语(斯里兰卡)", L"සිංහල" },
{ "uz_UZ", L"乌兹别克语", L"Ўзбекча" },
};
static const std::size_t kLanguageCount =
sizeof(kLanguages) / sizeof(kLanguages[0]);
inline std::string ToLanguageTag(const char* code) {
std::string tag(code);
std::replace(tag.begin(), tag.end(), '_', '-');
return tag;
}
inline const wchar_t* DisplayName(
const LanguageOption& option,
bool chineseUi) {
return chineseUi ? option.zhName : option.nativeName;
}
inline const LanguageOption* FindLanguage(const std::string& code) {
for (std::size_t i = 0; i < kLanguageCount; ++i) {
if (code == kLanguages[i].code) {
return &kLanguages[i];
}
}
return 0;
}
调用示例:
const LanguageOption* option = FindLanguage("fil_PH");
if (option != 0) {
const std::string languageTag = ToLanguageTag(option->code); // fil-PH
const wchar_t* uiText = DisplayName(*option, false); // Filipino
}
源码应保存为 UTF-8 BOM,或在 MSVC 中启用 /utf-8。跨平台 C++ 项目也可以将显示名称改成 UTF-8 std::string。C++ 标准库没有统一接收 BCP 47 的 locale 构造接口,转换后的标签通常传给 Qt、ICU 或 Web API。
5.4 C# / .NET
下面的写法不依赖 record,可以覆盖更多旧版 C# 项目:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
public sealed class LanguageOption
{
public string Code { get; private set; }
public string ZhName { get; private set; }
public string NativeName { get; private set; }
public LanguageOption(string code, string zhName, string nativeName)
{
Code = code;
ZhName = zhName;
NativeName = nativeName;
}
public string ToLanguageTag()
{
return Code.Replace('_', '-');
}
public CultureInfo ToCultureInfo()
{
return CultureInfo.GetCultureInfo(ToLanguageTag());
}
public string DisplayName(bool chineseUi)
{
return chineseUi ? ZhName : NativeName;
}
}
public static class LanguageCatalog
{
public static readonly ReadOnlyCollection<LanguageOption> All =
new List<LanguageOption>
{
new LanguageOption("zh_CN", "简体中文", "简体中文"),
new LanguageOption("zh_TW", "繁体中文(台湾)", "繁體中文(台灣)"),
new LanguageOption("zh_HK", "繁体中文(香港)", "繁體中文(香港)"),
new LanguageOption("nl_NL", "荷兰语", "Nederlands (Nederland)"),
new LanguageOption("nl_BE", "荷兰语(比利时)", "Nederlands (België)"),
new LanguageOption("en_US", "英语(美国)", "English (United States)"),
new LanguageOption("en_AU", "英语(澳大利亚)", "English (Australia)"),
new LanguageOption("en_CA", "英语(加拿大)", "English (Canada)"),
new LanguageOption("en_IN", "英语(印度)", "English (India)"),
new LanguageOption("en_IE", "英语(爱尔兰)", "English (Ireland)"),
new LanguageOption("en_NZ", "英语(新西兰)", "English (New Zealand)"),
new LanguageOption("en_SG", "英语(新加坡)", "English (Singapore)"),
new LanguageOption("en_ZA", "英语(南非)", "English (South Africa)"),
new LanguageOption("en_GB", "英语(英国)", "English (United Kingdom)"),
new LanguageOption("fr_FR", "法语", "Français (France)"),
new LanguageOption("fr_BE", "法语(比利时)", "Français (Belgique)"),
new LanguageOption("fr_CA", "法语(加拿大)", "Français (Canada)"),
new LanguageOption("fr_CH", "法语(瑞士)", "Français (Suisse)"),
new LanguageOption("de_DE", "德语", "Deutsch (Deutschland)"),
new LanguageOption("de_LI", "德语(列支敦斯登)", "Deutsch (Liechtenstein)"),
new LanguageOption("de_AT", "德语(奥地利)", "Deutsch (Österreich)"),
new LanguageOption("de_CH", "德语(瑞士)", "Deutsch (Schweiz)"),
new LanguageOption("it_IT", "意大利语", "Italiano (Italia)"),
new LanguageOption("it_CH", "意大利语(瑞士)", "Italiano (Svizzera)"),
new LanguageOption("pt_BR", "葡萄牙语(巴西)", "Português (Brasil)"),
new LanguageOption("pt_PT", "葡萄牙语", "Português (Portugal)"),
new LanguageOption("es_ES", "西班牙语", "Español (España)"),
new LanguageOption("es_US", "西班牙语(美国)", "Español (Estados Unidos)"),
new LanguageOption("bn_BD", "孟加拉语", "বাংলা (বাংলাদেশ)"),
new LanguageOption("bn_IN", "孟加拉语(印度)", "বাংলা (ভারত)"),
new LanguageOption("hr_HR", "克罗地亚语", "Hrvatski"),
new LanguageOption("cs_CZ", "捷克语", "Čeština"),
new LanguageOption("da_DK", "丹麦语", "Dansk"),
new LanguageOption("el_GR", "希腊语", "Ελληνικά"),
new LanguageOption("he_IL", "希伯来语(以色列)", "עברית"),
new LanguageOption("hi_IN", "印地语", "हिन्दी"),
new LanguageOption("hu_HU", "匈牙利语", "Magyar"),
new LanguageOption("id_ID", "印度尼西亚语", "Bahasa Indonesia"),
new LanguageOption("ja_JP", "日语", "日本語"),
new LanguageOption("ko_KR", "韩语", "한국어"),
new LanguageOption("ms_MY", "马来语", "Melayu"),
new LanguageOption("fa_IR", "波斯语", "فارسی"),
new LanguageOption("pl_PL", "波兰语", "Polski"),
new LanguageOption("ro_RO", "罗马尼亚语", "Română"),
new LanguageOption("ru_RU", "俄语", "Русский"),
new LanguageOption("sr_RS", "塞尔维亚语", "Српски"),
new LanguageOption("sv_SE", "瑞典语", "Svenska"),
new LanguageOption("th_TH", "泰语", "ไทย"),
new LanguageOption("tr_TR", "土耳其语", "Türkçe"),
new LanguageOption("ur_PK", "乌尔都语", "اردو"),
new LanguageOption("vi_VN", "越南语", "Tiếng Việt"),
new LanguageOption("ca_ES", "加泰罗尼亚语(西班牙)", "Català"),
new LanguageOption("lv_LV", "拉脱维亚语", "Latviešu"),
new LanguageOption("lt_LT", "立陶宛语", "Lietuvių"),
new LanguageOption("nb_NO", "书面挪威语", "Norsk bokmål"),
new LanguageOption("sk_SK", "斯洛伐克语", "Slovenčina"),
new LanguageOption("sl_SI", "斯洛文尼亚语", "Slovenščina"),
new LanguageOption("bg_BG", "保加利亚语", "Български"),
new LanguageOption("uk_UA", "乌克兰语", "Українська"),
new LanguageOption("fil_PH", "菲律宾语", "Filipino"),
new LanguageOption("fi_FI", "芬兰语", "Suomi"),
new LanguageOption("af_ZA", "南非荷兰语", "Afrikaans"),
new LanguageOption("rm_CH", "罗曼什语(瑞士)", "Rumantsch"),
new LanguageOption("km_KH", "高棉语", "ខ្មែរ"),
new LanguageOption("my_MM", "缅甸语", "မြန်မာ"),
new LanguageOption("am_ET", "阿姆哈拉语(埃塞俄比亚)", "አማርኛ"),
new LanguageOption("be_BY", "白俄罗斯语", "Беларуская"),
new LanguageOption("et_EE", "爱沙尼亚语", "Eesti"),
new LanguageOption("sw_TZ", "斯瓦希里语(坦桑尼亚)", "Kiswahili"),
new LanguageOption("zu_ZA", "祖鲁语(南非)", "IsiZulu"),
new LanguageOption("az_AZ", "阿塞拜疆语", "Azərbaycan"),
new LanguageOption("hy_AM", "亚美尼亚语(亚美尼亚)", "Հայերեն"),
new LanguageOption("ka_GE", "格鲁吉亚语(格鲁吉亚)", "ქართული"),
new LanguageOption("lo_LA", "老挝语(老挝)", "ລາວ"),
new LanguageOption("mn_MN", "蒙古语", "Монгол"),
new LanguageOption("ne_NP", "尼泊尔语", "नेपाली"),
new LanguageOption("kk_KZ", "哈萨克语", "Қазақ тілі"),
new LanguageOption("si_LK", "僧伽罗语(斯里兰卡)", "සිංහල"),
new LanguageOption("uz_UZ", "乌兹别克语", "Ўзбекча"),
}.AsReadOnly();
public static LanguageOption FindByCode(string code)
{
foreach (LanguageOption option in All)
{
if (string.Equals(option.Code, code, StringComparison.Ordinal))
{
return option;
}
}
return null;
}
}
调用示例:
var option = LanguageCatalog.FindByCode("fil_PH");
if (option != null)
{
var culture = option.ToCultureInfo(); // fil-PH
var uiText = option.DisplayName(chineseUi: false); // Filipino
}
5.5 JavaScript / TypeScript
下面的代码本身是有效 JavaScript,同时通过 JSDoc 为 TypeScript 和编辑器提供类型信息:
/**
* @typedef {Readonly<{
* code: string,
* zhName: string,
* nativeName: string
* }>} LanguageOption
*/
/** @type {ReadonlyArray<LanguageOption>} */
const LANGUAGE_OPTIONS = Object.freeze([
{ code: "zh_CN", zhName: "简体中文", nativeName: "简体中文" },
{ code: "zh_TW", zhName: "繁体中文(台湾)", nativeName: "繁體中文(台灣)" },
{ code: "zh_HK", zhName: "繁体中文(香港)", nativeName: "繁體中文(香港)" },
{ code: "nl_NL", zhName: "荷兰语", nativeName: "Nederlands (Nederland)" },
{ code: "nl_BE", zhName: "荷兰语(比利时)", nativeName: "Nederlands (België)" },
{ code: "en_US", zhName: "英语(美国)", nativeName: "English (United States)" },
{ code: "en_AU", zhName: "英语(澳大利亚)", nativeName: "English (Australia)" },
{ code: "en_CA", zhName: "英语(加拿大)", nativeName: "English (Canada)" },
{ code: "en_IN", zhName: "英语(印度)", nativeName: "English (India)" },
{ code: "en_IE", zhName: "英语(爱尔兰)", nativeName: "English (Ireland)" },
{ code: "en_NZ", zhName: "英语(新西兰)", nativeName: "English (New Zealand)" },
{ code: "en_SG", zhName: "英语(新加坡)", nativeName: "English (Singapore)" },
{ code: "en_ZA", zhName: "英语(南非)", nativeName: "English (South Africa)" },
{ code: "en_GB", zhName: "英语(英国)", nativeName: "English (United Kingdom)" },
{ code: "fr_FR", zhName: "法语", nativeName: "Français (France)" },
{ code: "fr_BE", zhName: "法语(比利时)", nativeName: "Français (Belgique)" },
{ code: "fr_CA", zhName: "法语(加拿大)", nativeName: "Français (Canada)" },
{ code: "fr_CH", zhName: "法语(瑞士)", nativeName: "Français (Suisse)" },
{ code: "de_DE", zhName: "德语", nativeName: "Deutsch (Deutschland)" },
{ code: "de_LI", zhName: "德语(列支敦斯登)", nativeName: "Deutsch (Liechtenstein)" },
{ code: "de_AT", zhName: "德语(奥地利)", nativeName: "Deutsch (Österreich)" },
{ code: "de_CH", zhName: "德语(瑞士)", nativeName: "Deutsch (Schweiz)" },
{ code: "it_IT", zhName: "意大利语", nativeName: "Italiano (Italia)" },
{ code: "it_CH", zhName: "意大利语(瑞士)", nativeName: "Italiano (Svizzera)" },
{ code: "pt_BR", zhName: "葡萄牙语(巴西)", nativeName: "Português (Brasil)" },
{ code: "pt_PT", zhName: "葡萄牙语", nativeName: "Português (Portugal)" },
{ code: "es_ES", zhName: "西班牙语", nativeName: "Español (España)" },
{ code: "es_US", zhName: "西班牙语(美国)", nativeName: "Español (Estados Unidos)" },
{ code: "bn_BD", zhName: "孟加拉语", nativeName: "বাংলা (বাংলাদেশ)" },
{ code: "bn_IN", zhName: "孟加拉语(印度)", nativeName: "বাংলা (ভারত)" },
{ code: "hr_HR", zhName: "克罗地亚语", nativeName: "Hrvatski" },
{ code: "cs_CZ", zhName: "捷克语", nativeName: "Čeština" },
{ code: "da_DK", zhName: "丹麦语", nativeName: "Dansk" },
{ code: "el_GR", zhName: "希腊语", nativeName: "Ελληνικά" },
{ code: "he_IL", zhName: "希伯来语(以色列)", nativeName: "עברית" },
{ code: "hi_IN", zhName: "印地语", nativeName: "हिन्दी" },
{ code: "hu_HU", zhName: "匈牙利语", nativeName: "Magyar" },
{ code: "id_ID", zhName: "印度尼西亚语", nativeName: "Bahasa Indonesia" },
{ code: "ja_JP", zhName: "日语", nativeName: "日本語" },
{ code: "ko_KR", zhName: "韩语", nativeName: "한국어" },
{ code: "ms_MY", zhName: "马来语", nativeName: "Melayu" },
{ code: "fa_IR", zhName: "波斯语", nativeName: "فارسی" },
{ code: "pl_PL", zhName: "波兰语", nativeName: "Polski" },
{ code: "ro_RO", zhName: "罗马尼亚语", nativeName: "Română" },
{ code: "ru_RU", zhName: "俄语", nativeName: "Русский" },
{ code: "sr_RS", zhName: "塞尔维亚语", nativeName: "Српски" },
{ code: "sv_SE", zhName: "瑞典语", nativeName: "Svenska" },
{ code: "th_TH", zhName: "泰语", nativeName: "ไทย" },
{ code: "tr_TR", zhName: "土耳其语", nativeName: "Türkçe" },
{ code: "ur_PK", zhName: "乌尔都语", nativeName: "اردو" },
{ code: "vi_VN", zhName: "越南语", nativeName: "Tiếng Việt" },
{ code: "ca_ES", zhName: "加泰罗尼亚语(西班牙)", nativeName: "Català" },
{ code: "lv_LV", zhName: "拉脱维亚语", nativeName: "Latviešu" },
{ code: "lt_LT", zhName: "立陶宛语", nativeName: "Lietuvių" },
{ code: "nb_NO", zhName: "书面挪威语", nativeName: "Norsk bokmål" },
{ code: "sk_SK", zhName: "斯洛伐克语", nativeName: "Slovenčina" },
{ code: "sl_SI", zhName: "斯洛文尼亚语", nativeName: "Slovenščina" },
{ code: "bg_BG", zhName: "保加利亚语", nativeName: "Български" },
{ code: "uk_UA", zhName: "乌克兰语", nativeName: "Українська" },
{ code: "fil_PH", zhName: "菲律宾语", nativeName: "Filipino" },
{ code: "fi_FI", zhName: "芬兰语", nativeName: "Suomi" },
{ code: "af_ZA", zhName: "南非荷兰语", nativeName: "Afrikaans" },
{ code: "rm_CH", zhName: "罗曼什语(瑞士)", nativeName: "Rumantsch" },
{ code: "km_KH", zhName: "高棉语", nativeName: "ខ្មែរ" },
{ code: "my_MM", zhName: "缅甸语", nativeName: "မြန်မာ" },
{ code: "am_ET", zhName: "阿姆哈拉语(埃塞俄比亚)", nativeName: "አማርኛ" },
{ code: "be_BY", zhName: "白俄罗斯语", nativeName: "Беларуская" },
{ code: "et_EE", zhName: "爱沙尼亚语", nativeName: "Eesti" },
{ code: "sw_TZ", zhName: "斯瓦希里语(坦桑尼亚)", nativeName: "Kiswahili" },
{ code: "zu_ZA", zhName: "祖鲁语(南非)", nativeName: "IsiZulu" },
{ code: "az_AZ", zhName: "阿塞拜疆语", nativeName: "Azərbaycan" },
{ code: "hy_AM", zhName: "亚美尼亚语(亚美尼亚)", nativeName: "Հայերեն" },
{ code: "ka_GE", zhName: "格鲁吉亚语(格鲁吉亚)", nativeName: "ქართული" },
{ code: "lo_LA", zhName: "老挝语(老挝)", nativeName: "ລາວ" },
{ code: "mn_MN", zhName: "蒙古语", nativeName: "Монгол" },
{ code: "ne_NP", zhName: "尼泊尔语", nativeName: "नेपाली" },
{ code: "kk_KZ", zhName: "哈萨克语", nativeName: "Қазақ тілі" },
{ code: "si_LK", zhName: "僧伽罗语(斯里兰卡)", nativeName: "සිංහල" },
{ code: "uz_UZ", zhName: "乌兹别克语", nativeName: "Ўзбекча" }
].map((item) => Object.freeze(item)));
const findLanguage = (code) =>
LANGUAGE_OPTIONS.find((item) => item.code === code);
const toLanguageTag = ({ code }) => code.replace("_", "-");
const displayName = (option, chineseUi) =>
chineseUi ? option.zhName : option.nativeName;
调用示例:
const option = findLanguage("fil_PH");
if (option) {
const languageTag = toLanguageTag(option); // fil-PH
const uiText = displayName(option, false); // Filipino
const formatter = new Intl.DateTimeFormat(languageTag); // 标准 API 使用 fil-PH
}
Web 页面还可以将转换后的标签写入 <html lang="fil-PH">。产品语言列表仍显示固定的 zhName 或 nativeName,不要用 Intl.DisplayNames 动态替换。
5.6 其他编程语言
Go、Python、Rust 等语言可以直接读取 5.1 节的完整 JSON。接入时只需保持相同边界:
- 记录固定包含
code、zhName、nativeName。 - 应用内持久化和系统间通信使用原始
code,例如fil_PH。 - 调用只接受 BCP 47 的标准库或外部接口前,将
_转为-,得到fil-PH。 - UI 显示直接选择
zhName或nativeName,不要让运行时重新生成产品名称。
6. 多技术栈如何避免再次分叉
不要分别手工维护 Java、C++、C# 和前端语言表。更稳妥的做法是建立一份 UTF-8 JSON 真值文件,再通过生成脚本输出各语言所需的常量或资源文件:
language-catalog.json
├─ 生成 Java LanguageOptions
├─ 生成 C++ LanguageOptions
├─ 生成 C# LanguageOptions
└─ 生成 JavaScript/TypeScript LanguageOptions
真值文件由人工审查,生成物禁止手工修改。持续集成可以重新生成一次并检查工作区是否出现差异,以便及时发现漏同步。
7. 同步检查清单
修改或新增语言后,至少确认:
8. 标准参考
- IANA Language Subtag Registry
- Unicode Common Locale Data Repository
- Unicode CLDR locale display names
外部标准负责提供代码和语言数据依据;应用自身仍需明确最终采用的内部格式、显示文字和兼容策略。
| 版权声明 本博客所有的原创文章,作者皆保留版权。转载必须包含本声明,保持本文完整,并以超链接形式注明作者 BensonLaur 和本文原始地址: |

浙公网安备 33010602011771号