windows 上的 kestrel 和 macOs/linux 上的 kestrel 之间的日期反序列化差异
Date deserialization difference between kestrel on windows and kestrel on macOs/linux
我曾尝试搜索有关 net.core 文档(问题等)的信息,但没有结果。
代码更简单:
[HttpGet()]
[Route("dob")]
public string dobTest()
{
var content = @"""1942-01-01T22:00:00.000Z""";
var settings = new JsonSerializerSettings()
{
//DateFormatHandling = DateFormatHandling.IsoDateFormat,
//DateParseHandling = DateParseHandling.DateTimeOffset,
DateTimeZoneHandling = DateTimeZoneHandling.Local,
//DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind
};
var dob = JsonConvert.DeserializeObject<DateTime>(content, settings);
return $"dob: {dob.ToString("yyyy-MM-dd HH:mm:ss.fff")} - {dob.Kind}";
}
如果我 运行 此代码在 Mac 或 Linux 上,结果是:
dob: 1942-01-02 00:00:00.000 - Local
如果我 运行 这个代码在 windows 上,结果是:
dob: 1942-01-01 23:00:00.000 - Local
我的 MacOs 时区设置在罗马 (UTC +01:00)
Windows 时区设置在罗马 (UTC +01:00)
Newtonsoft.Json的版本是12.0.3
net framework的版本是net core 3.1
Linux 和 OSX 都使用 IANA time zone database for its primary source of time zone information, which has correct historical data for time zones in 1942 in Rome, under the identifier Europe/Rome
. You can see that UTC+2 is the correct offset for the date given here。
另一方面,Windows 没有该时区的历史记录。等效的 Windows 标识符是 W. Europe Standard Time
,它的英文显示名称是 (UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna
。您可以在注册表中的以下键下看到 Windows 的数据:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\W. Europe Standard Time
如果您使用 RegEdit 检查此键,您会注意到与其他几个时区不同,此时区没有 Dynamic DST
子键。这意味着 Windows 不知道 DST 规则中的任何历史差异,因此每年都在同一组规则下进行处理。
Windows 确实有 某些 区域的历史数据,但一般来说,Microsoft 仅根据其 DST/TZ support policy.[=18= 保证自 2010 年以来的历史准确性]
因此,如果您的应用程序需要历史时区准确性,那么您应该只使用 IANA 时区。在 .NET 中,您可以使用 Noda Time 库中的 TZDB 提供程序来执行此操作。
我曾尝试搜索有关 net.core 文档(问题等)的信息,但没有结果。 代码更简单:
[HttpGet()]
[Route("dob")]
public string dobTest()
{
var content = @"""1942-01-01T22:00:00.000Z""";
var settings = new JsonSerializerSettings()
{
//DateFormatHandling = DateFormatHandling.IsoDateFormat,
//DateParseHandling = DateParseHandling.DateTimeOffset,
DateTimeZoneHandling = DateTimeZoneHandling.Local,
//DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind
};
var dob = JsonConvert.DeserializeObject<DateTime>(content, settings);
return $"dob: {dob.ToString("yyyy-MM-dd HH:mm:ss.fff")} - {dob.Kind}";
}
如果我 运行 此代码在 Mac 或 Linux 上,结果是:
dob: 1942-01-02 00:00:00.000 - Local
如果我 运行 这个代码在 windows 上,结果是:
dob: 1942-01-01 23:00:00.000 - Local
我的 MacOs 时区设置在罗马 (UTC +01:00) Windows 时区设置在罗马 (UTC +01:00)
Newtonsoft.Json的版本是12.0.3 net framework的版本是net core 3.1
Linux 和 OSX 都使用 IANA time zone database for its primary source of time zone information, which has correct historical data for time zones in 1942 in Rome, under the identifier Europe/Rome
. You can see that UTC+2 is the correct offset for the date given here。
Windows 没有该时区的历史记录。等效的 Windows 标识符是 W. Europe Standard Time
,它的英文显示名称是 (UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna
。您可以在注册表中的以下键下看到 Windows 的数据:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\W. Europe Standard Time
如果您使用 RegEdit 检查此键,您会注意到与其他几个时区不同,此时区没有 Dynamic DST
子键。这意味着 Windows 不知道 DST 规则中的任何历史差异,因此每年都在同一组规则下进行处理。
Windows 确实有 某些 区域的历史数据,但一般来说,Microsoft 仅根据其 DST/TZ support policy.[=18= 保证自 2010 年以来的历史准确性]
因此,如果您的应用程序需要历史时区准确性,那么您应该只使用 IANA 时区。在 .NET 中,您可以使用 Noda Time 库中的 TZDB 提供程序来执行此操作。