在 Windows 中使用 TimeZoneInfo 并呼叫 TryConvertWindowsIdToIanaId 的

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" 软体製作。

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章

5 点赞(415) 阅读(67)