由于开发者不熟悉不同操作系统管理时区的方式,当用.Net Core开发与时区相关的应用运行在不同操作系统上会出现错误。这片文章将会探索一下在不同操作系统上用.Net Core 使用时区信息出现的问题与解决方案
问题重现
假设你用.Net Core 开发一个获取特定时区信息的控制台程序,你可能会这样写:
1 | static void Main(string[] args) |
这个程序在我win10系统上运行,我看到如下输出:
1 | (UTC-06:00) Central Time (US & Canada) |
如果我把该程序在我的ubuntu上运行,我看到抛出了下面的异常信息
1 | xception has occurred: CLR/System.TimeZoneNotFoundException |
这其中发生了什么?让我们花一点时间深入研究和探索这其中到底真正是什么原因造成的。
时区的不同
windows系统通过windows注册表来维护一个时区列表。在这里你能发现这些列表的值。
相反,linux系统通过 Internet Assigned Numbers Authority (IANA)维护的时区数据库。你能在IANA的网站找到最新的数据。这里是一个IANA 时区的例子
1 | America/New_York |
当你使用上面两种格式的其中一种开发.Net Core 代码,然后运行你的程序在另外一种操作系统时候,这个问题就会出现。如果你出现了这样的问题,你需要处理不同操作系统下的时区管理方式,因为.Net Core 运行时只会遵循当前正在运行测操作系统的时区管理机制。
我们该如何解决这个问题?
在github上有一个能解决这个问题的开源项目。你可以参考这个项目的作者贡献的源代码。你也可以用下面的命令行的方式在nuget上获取这个包。
1 | Install-Package TimeZoneConverter |
完成安装后,你就可以在不同操作系统上使用统一的方式区解决时区的问题。
1 | TimeZoneInfo tzi = TZConvert.GetTimeZoneInfo("Central Standard Time"); |
因为时区数据是经常更新的,所以你需要留意这个项目的文档,确保你的安装包是最新的。