TimeZoneInfo.FindSystemTimeZoneById() 在 Unity 应用程序中抛出异常

TimeZoneInfo.FindSystemTimeZoneById() throws exception in a Unity application

如果我在 C# 控制台应用程序中执行此代码,它工作正常。

TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
Console.WriteLine(easternZone.DisplayName);

但是,当我在Unity应用程序中使用相同的方法时,抛出异常:

System.TimeZoneNotFoundException: Exception of type 'System.TimeZoneNotFoundException' was thrown.
  at System.TimeZoneInfo.FindSystemTimeZoneByFileName (System.String id, System.String filepath) [0x00000] in <filename unknown>:0
  at System.TimeZoneInfo.FindSystemTimeZoneById (System.String id) [0x00000] in <filename unknown>:0
  ...

我注意到的一件奇怪的事情是,当 MSDN 文档明确指出信息是从注册表中检索时,在名为 "FindSystemTimeZoneByFileName" 的方法中抛出了异常。

Unity 应用程序使用 Mono,并且可以针对 non-Windows 系统 - 因此注册表信息并不总是可用。似乎 Mono 将使用系统上可用的任何时区信息,无论是 Windows 时区还是 IANA 时区 - 因此,您可能需要检查一个或另一个,或两者:

TimeZoneInfo easternZone;

try
{
    easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
}
catch (TimeZoneNotFoundException)
{
    easternZone = TimeZoneInfo.FindSystemTimeZoneById("America/New_York");
}

当然,如果您通常要在 non-Windows 平台上 运行,则可以取消这些设置。如果两者都没有找到,那么它仍然会抛出异常。

您可以查看 the list of IANA time zones here. You may also want to read the timezone tag wiki 以了解其中的区别。

Update:作为 pointed out, you can now use my TimeZoneConverter库完成这个。虽然不再需要上面的代码,但您现在可以简单地这样做:

TimeZoneInfo easternZone = TZConvert.GetTimeZoneInfo(timeZoneName);

timeZoneName参数可以是America/New_YorkEastern Standard Time.

郑重声明,有一个名为 TimeZoneConverter 的小程序包可以为您执行此操作,而无需捕获异常:

if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
    timeZoneName = TZConvert.WindowsToIana(timeZoneName);
}
var zoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName);