Windows 上如果设定了时区(无论手动或自动),透过 TimeZoneInfo 取出的时区识别码,都是根据所设定的地区的时区,并且回应成 Windows 使用的 TimeZone 格式。
例如设定为 (UTC +08:00) 台北取出来的 Id 值会为:"Taipei Standard Time" 的字串资料。
但是…
如果需要跨平台到其他的系统当中使用此资料,例如: macOS、Linux 则需要转换基于 Time Zone Database 所使用的 Iana 时间格式 来运用,所以如果在 .NET 6 以后的 .NET 程式,已经可以透过 TimeZoneInfo 的 TryConvertWindowsIdToIanaId 方法来进行转换。
也就是说如果在 Windows 上要取得当前电脑所设定的时区抛去给其他系统使用时,在 .NET 6 以后的 .NET 程式可以这样处理:
var timeZoneInfoLocal = TimeZoneInfo.Local;
Console.WriteLine($"Local Id: {timeZoneInfoLocal.Id}, UtcOffSet: {timeZoneInfoLocal.BaseUtcOffset}");
var windowsId = timeZoneInfoLocal.Id;
Console.WriteLine($"WindowsId: {windowsId}");
TimeZoneInfo.TryConvertWindowsIdToIanaId(windowsId, out var ianaId);
Console.WriteLine($"IanaId: {ianaId}");
其输出结果大致上为:
Local Id: Taipei Standard Time, UtcOffSet: 08:00:00
WindowsId: Taipei Standard Time
IanaId: Asia/Taipei
透过 LINQPad 来做上述程式的测试与结果展示:
其结果相当合理。
且此方法是从 .NET 6 开始就有的 .NET API,应该没什么太大问题。
果然…不出意外马上就要出意外了。
没多久就发现在某些 Windows 设备上且确定是 UTC+08:00 的 Taipei 时区,使用此转换方式居然失效,所转换出来的 "ianaId" 值居然是 Null,且 TryConvertWindowsIdToIanaId 方法还回传了 false。
赶紧仔细研读了文件上的 "备注":
并且注意到了 "NLS 模式"。
连结过去看了 ".NET 全球化和 ICU" 的文件说明,在 Windows 上的 ICU 说明为:
其中 ICU 相依 API 的更点出了该 TryConvertWindowsIdToIanaId 方法 并特别说明:
结果就是中枪,这些设备的执行的环境完全符合 "NLS 模式" 的执行,未能正确使用 ICU。
所以各位看倌,要使用 .NET API 时文件内容一定要看清楚阿…
解决方式呢?
方案 A:
是在程式中安装 "Microsoft.ICU.ICU4C.Runtime" 的 Nuget 套件并且採用 "应用程式本机 ICU" 所描述的三种方式的任何其中一种方式进行设定:
方案 B:
透过 NodaTime 来进行:
var windowsId = TimeZoneInfo.Local.Id;
var ianaTimeZoneId = TzdbDateTimeZoneSource.Default
.WindowsMapping.PrimaryMapping.TryGetValue(windowsId, out var ianaId)
? ianaId
: string.Empty;
if (!string.IsNullOrEmpty(ianaTimeZoneId))
{
Console.WriteLine($"WindowsId: {windowsId}");
Console.WriteLine($"IanaId: {ianaId}");
}
else
{
Console.WriteLine("No IANA mapping found for the given Windows time zone.");
}
其输出结果大致上为:
WindowsId: Taipei Standard Time
IanaId: Asia/Taipei
透过 LINQPad 来做上述程式的测试与结果展示:
以上结案~~~
I'm a Microsoft MVP - Developer Technologies (From 2015 ~).
I focus on the following topics: Xamarin Technology, Azure, Mobile DevOps, and Microsoft EM+S.
If you want to know more about them, welcome to my website:
https://jamestsai.tw
本部落格文章之图片相关后製处理皆透过 Techsmith 公司 所赞助其授权使用之 "Snagit" 与 "Snagit Editor" 软体製作。