【问题标题】:TimeZoneInfo.FindSystemTimeZoneById() throws exception in a Unity applicationTimeZoneInfo.FindSystemTimeZoneById() 在 Unity 应用程序中引发异常
【发布时间】:2016-05-04 17:43:40
【问题描述】:

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

【问题讨论】:

    标签: c# timezone unity3d-5


    【解决方案1】:

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

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

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

    您可以查看the list of IANA time zones here。您可能还想阅读the timezone tag wiki 以了解区别。

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

    TimeZoneInfo easternZone = TZConvert.GetTimeZoneInfo(timeZoneName);
    

    timeZoneName 参数可以是任一 America/New_YorkEastern Standard Time

    【讨论】:

    • 非常感谢您的快速回答和您提供的链接。我非常有信心它会解决问题,但不幸的是它没有。事实上,我意识到我什至无法使用TimeZoneInfo.GetSystemTimeZones() 获得可用时区列表。我猜这个问题不只是在 Mono 上,而是与 Unity 或我们在项目中使用的任何其他库相关的其他问题。我会继续挖掘,
    • 我在这个问题上投入了更多时间,发现实际上这是一个 Unity 错误,如下所述:issuetracker.unity3d.com/issues/…
    • 感谢您的跟进。让我们知道他们是否修复它。 :)
    • 您可能想看看Noda Time 是否可以在 Unity 中运行。无论如何,这会给你一个替代选择。
    【解决方案2】:

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

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

    【讨论】:

    • 仅供参考,版本 2.0.0 及更高版本内置了操作系统平台检查,因此您可以直接写 zoneInfo = TZConvert.GetTimeZoneInfo(timeZoneName)
    • @MattJohnson-Pint 如果是这种情况,有什么建议,我仍然看到异常?
    猜你喜欢
    • 1970-01-01
    • 2016-12-22
    • 2012-04-08
    • 2020-08-13
    • 2017-05-18
    • 2014-09-07
    • 1970-01-01
    • 2022-10-07
    • 2016-01-04
    相关资源
    最近更新 更多