9

如果我在 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”的方法中引发的。

4

2 回答 2

20

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

TimeZoneInfo easternZone;

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

当然,如果您通常要在非 Windows 平台上运行,您可以反转这些。如果两者都没有找到,那么它仍然会抛出异常。

您可以在此处查看 IANA 时区列表。您可能还想阅读时区标签 wiki以了解区别。

更新:正如Shaul 的回答所指出的,您现在可以使用我的TimeZoneConverter库来完成此操作。虽然不再需要上面的代码,但您现在可以简单地执行此操作:

TimeZoneInfo easternZone = TZConvert.GetTimeZoneInfo(timeZoneName);

参数timeZoneName可以是 America/New_YorkEastern Standard Time

于 2016-01-27T17:09:42.987 回答
7

作为记录,有一个名为TimeZoneConverter的不错的小程序包可以为您执行此操作,而无需捕获异常:

if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
    timeZoneName = TZConvert.WindowsToIana(timeZoneName);
}
var zoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName); 
于 2018-05-03T09:27:13.347 回答