各ロケールのCultureInfoのParentプロパティを辿るとInvariantCultureに辿り着きますが、その一つ前までをまとめてMarkdownの表を生成するコードが以下のとおり。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Globalization; | |
using System.Linq; | |
using System.Text; | |
static string CreateLocaleTable(string cultureName) | |
{ | |
var paths = CultureInfo.GetCultures(CultureTypes.AllCultures) | |
.Where(x => x.Name.StartsWith(cultureName)) | |
.Select(x => (culture: x, path: GetParent(x))) | |
.ToArray(); | |
var length = paths.Max(x => x.path.Length); | |
var lines = new StringBuilder() | |
.AppendLine(string.Join("|", Enumerable.Repeat("<--", length - 1).Prepend(null).Prepend(null).Append(null).Append(null))) | |
.AppendLine(string.Join("|", Enumerable.Repeat("---", length + 1).Prepend(null).Append(null))); | |
var buffer = paths.Select(x => (x.culture, path: x.path.Concat(new CultureInfo[length - 1]).Take(length).ToArray())) | |
.OrderBy(x => x.path[0].Name); | |
for (int i = 1; i < length; i++) | |
{ | |
int index = i; | |
buffer = buffer.ThenBy(x => x.path[index]?.Name); | |
} | |
foreach (var (culture, path) in buffer) | |
{ | |
lines.AppendLine(string.Join("|", path.Select(x => x?.Name).Append(culture.DisplayName).Prepend(null).Append(null))); | |
} | |
return lines.ToString(); | |
static CultureInfo[] GetParent(CultureInfo c, List<CultureInfo> list = null) | |
{ | |
list ??= new List<CultureInfo>(); | |
list.Insert(0, c); | |
return (c.Parent == CultureInfo.InvariantCulture) | |
? list.ToArray() | |
: GetParent(c.Parent, list); | |
} | |
} |
<-- | <-- | <-- | ||
---|---|---|---|---|
zh | 中国語 | |||
zh | zh-Hans | 簡体字中国語 | ||
zh | zh-Hans | zh-CHS | 簡体字中国語レガシ | |
zh | zh-Hans | zh-CHS | zh-CN | 中国語 (簡体字、中国) |
zh | zh-Hans | zh-CHS | zh-Hans-HK | 中国語 (簡体字、香港特別行政区) |
zh | zh-Hans | zh-CHS | zh-Hans-MO | 中国語 (簡体字、マカオ SAR) |
zh | zh-Hans | zh-CHS | zh-SG | 中国語 (簡体字、シンガポール) |
zh | zh-Hant | 繁体字中国語 | ||
zh | zh-Hant | zh-CHT | 繁体字中国語レガシ | |
zh | zh-Hant | zh-CHT | zh-HK | 中国語 (繁体字、香港) |
zh | zh-Hant | zh-CHT | zh-MO | 中国語 (繁体字、マカオ) |
zh | zh-Hant | zh-CHT | zh-TW | 中国語 (繁体字、台湾) |
同じように、繁体字の場合、表示言語がzh-TW(台湾)のときはzh-TWのリソースがあればそれが、なければ(zh-CHTはスルーするとして)zh-Hantが存在すればそれが選択されますが、リソースをzh-TWで作成すると香港かマカオで表示言語に繁体字を使っているときには選択されないことになります。
したがって、簡体字のリソースはzh-Hansで、簡体字のリソースはzh-Hantで作成するのが正解で、もし分ける必要が出てきた場合に、その下のロケールで該当部分を上書きすればいいわけです。
念のため、.NET 5.0の上で実行した結果。
<-- | <-- | ||
---|---|---|---|
zh | 中国語 | ||
zh | zh-Hans | 中国語 (簡体字) | |
zh | zh-Hans | zh-CN | 中国語 (中国) |
zh | zh-Hans | zh-Hans-HK | 中文(简体,香港特别行政区) |
zh | zh-Hans | zh-Hans-MO | 中文(简体,澳门特别行政区) |
zh | zh-Hans | zh-SG | 中国語 (シンガポール) |
zh | zh-Hant | 中国語 (繁体字) | |
zh | zh-Hant | zh-HK | 中国語 (中華人民共和国香港特別行政区) |
zh | zh-Hant | zh-MO | 中国語 (中華人民共和国マカオ特別行政区) |
zh | zh-Hant | zh-TW | 中国語 (台湾) |
以上、中国語のロケールはそれぞれzh-Hansかzh-Hantにしておけばよい、という確認まで。