在unix上托管时,.NET Core中的TimeZoneInfo(nginx)

时间:2017-01-10 10:16:53

标签: c# .net nginx timezone .net-core

例如,当我尝试执行以下操作时。

TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time")

我收到错误消息,TimeZone在本地计算机上不可用。当我在本地运行它可以工作,但我在Windows上运行它。部署时,它在Nginx的Unix机器上运行。我可以看到FindSystemTimeZoneById在Unix上查找错误的文件夹。有没有办法让这项工作?

7 个答案:

答案 0 :(得分:12)

.Net Core使用系统时区。不幸的是,Windows和Linux有不同的时区系统。现在你有两种方式:

答案 1 :(得分:6)

你能试试吗?

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

您可以在此处查看IANA时区列表https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

答案 2 :(得分:4)

如果您想尝试Windows时区,然后在Windows时区不存在的情况下在IANA上进行回退:

var tzi  = TimeZoneInfo.GetSystemTimeZones().Any(x => x.Id == "Eastern Standard Time") ? 
    TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time") : 
    TimeZoneInfo.FindSystemTimeZoneById("America/New_York");

答案 3 :(得分:1)

关闭previous answer,我们可以通过检查运行的操作系统来避免昂贵的try/catch

using System;
using System.Runtime.InteropServices;

TimeZoneInfo easternStandardTime;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
  easternStandardTime = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
  easternStandardTime = TimeZoneInfo.FindSystemTimeZoneById("America/New_York");
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
  throw new NotImplementedException("I don't know how to do a lookup on a Mac.");
}

答案 4 :(得分:1)

快速而肮脏的解决方案:在 Windows 上的虚拟应用程序中使用 ToSerializedString 序列化您的 TimeZoneInfo,保存输出,然后在您需要的地方使用 FromSerializedString 反序列化。

在 Windows 上:

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

输出:

Eastern Standard Time;-300;(UTC-05:00) Eastern Time (US & Canada);Eastern Standard Time;Eastern Daylight Time;[01:01:0001;12:31:2006;60;[0;02:00:00;4;1;0;];[0;02:00:00;10;5;0;];][01:01:2007;12:31:9999;60;[0;02:00:00;3;2;0;];[0;02:00:00;11;1;0;];];

那么:

// TimeZoneInfo is immutable
public static readonly TimeZoneInfo EST = TimeZoneInfo.FromSerializedString(
            "Eastern Standard Time;-300;(UTC-05:00) Eastern Time (US & Canada);Eastern Standard Time;Eastern Daylight Time;[01:01:0001;12:31:2006;60;[0;02:00:00;4;1;0;];[0;02:00:00;10;5;0;];][01:01:2007;12:31:9999;60;[0;02:00:00;3;2;0;];[0;02:00:00;11;1;0;];];");

答案 5 :(得分:0)

通过执行以下操作,我能够在开发docker映像中支持该用例:

cp /usr/share/zoneinfo/America/Los_Angeles "/usr/share/zoneinfo/Pacific Standard Time"

很明显,我认为这对于生产部署不是一个好主意。但这在某些情况下可能会有所帮助。

答案 6 :(得分:0)

从 .NET 6 Preview 4 开始,it is finally possible 以跨平台方式处理时区。

TimeZoneInfo.FindSystemTimeZoneById(string) 方法会自动接受任一平台上的 Windows 或 IANA 时区,并在需要时进行转换。

// Both of these will now work on any supported OS where ICU and time zone data are available.
TimeZoneInfo tzi1 = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time");
TimeZoneInfo tzi2 = TimeZoneInfo.FindSystemTimeZoneById("Australia/Sydney");

请注意,如链接中所指定,基于 .NET Core Alpine Linux 的 Docker 映像 will not have the necessary tzdata installed by default,因此它必须安装在您的 Dockerfile 中才能正常工作。