我对意大利夏令时有意见在. NET中转换unix 687481200000看起来是不可预测的(当然我错过了一些东西).
正如你可以看到在浏览器控制台输入:
console.log(new Date(687481200000).toLocaleString('it-IT', {timeZone: 'Europe/Rome', timeZoneName: 'short'}));
unix timestamp值687481200000应该返回意大利日期1991—10—15 00:00:00(意大利的日期是15/10/1991,但我们总是谈论15 October).
现在我想让你们看看这个片段
https://dotnetfiddle.net/jKShoE
当我在浏览器中使用. NET 6运行它时,
意大利日期和时间:10/15/1991 00:00:00
将浏览器更改为. NET 4.7.2
https://dotnetfiddle.net/GV7FYD
我得到
意大利日期和时间:1991年10月15日凌晨1:00:00
如果我在Visual Studio 2022中的一个新的. NET 6项目中复制这些代码
意大利日期和时间:15/10/1991 01:00:00
有人能解释为什么吗? 有没有一种方法可以在不使用外部库的情况下获得正确的时间00:00:00?
PS:工作在Windows 10.0.19045 Build 19045,意大利本地化
Edit: here's the code from the fiddle.
using System;
public class Program
{
public static void Main()
{
long unixMilliseconds = 687481200000;
DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(unixMilliseconds);
TimeZoneInfo italianTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
DateTimeOffset italianDateTimeOffset = TimeZoneInfo.ConvertTime(dateTimeOffset, italianTimeZone);
DateTime italianDateTime = italianDateTimeOffset.DateTime;
Console.WriteLine("Data e ora italiane: " + italianDateTime);
}
}
Edit 2: Revised code
我不得不深入挖掘并找到更多的答案,一旦我搜索了timeZoneInfo. AdjustmentRule在stackoverflow上.
using System;
using System.Linq;
public class Program
{
public static void Main()
{
// A representation for UTC 14/10/1991 23:00:00 +00:00
long unixMilliseconds = 687481200000;
// Looking at epochconverter.com
// UTC 14/10/1991 23:00:00 +00:00
// corresponds to italian 15 october 1991 00:00:00 GMT+01:00
// Store the UTC time in dateTimeOffset
DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(unixMilliseconds);
Console.WriteLine(dateTimeOffset);
// .NET 6: 10/14/1991 23:00:00 +00:00
// .NET 4.7.2: 10/14/1991 11:00:00 PM +00:00
// Applying the following pattern:
// https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.fromunixtimemilliseconds?view=net-8.0#remarks
// I was wrong, my current timezone is "W. Europe Standard Time" but the nature of the problem remains unchanged.
// I retrieved my TimeZoneInfo this way:
TimeZoneInfo italianTimeZone = TimeZoneInfo.Local;
Console.WriteLine("TimeZoneInfo.Local.Id: " + TimeZoneInfo.Local.Id); // 我得到 here W. Europe Standard Time
// so retrieving it by ID to make it work on fiddler
italianTimeZone = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
Console.WriteLine("TimeZoneInfo Id: " + italianTimeZone.Id); // Once again to check
Console.WriteLine("TimeZoneInfo: " + italianTimeZone.ToString());
// .NET 6: (UTC+01:00) Central European Time (Berlin)
// .NET 4.7.2: (UTC+01:00) Amsterdam, Berlino, Berna, Roma, Stoccolma, Vienna
Console.WriteLine("Daylight : " + italianTimeZone.IsDaylightSavingTime(dateTimeOffset));
// fiddler .NET 6 : False
// fiddler .NET 4.7 : True
// "my PC" .NET 6 : True
// Now look at this:
Console.WriteLine("Rules count: " + italianTimeZone.GetAdjustmentRules().Length);
// fiddler .NET 6 : 79
// fiddler .NET 4.7 : 1
// "my PC" .NET 6 : 1
// Only in the fiddler .NET 6 the full set of rules is available.
// BONUS
string iso8601 = "1991-10-14T23:00:00Z";
long myDate = DateTimeOffset.Parse(iso8601).ToUnixTimeMilliseconds();
Console.WriteLine("My date: " + myDate); // My date: 687481200000 on every system
}
}
我仍然不清楚如何以及谁来管理时区数据库,无论是操作系统还是. NET框架,但在我看来,这个配置非常复杂,以至于我 Select 使用NodaTime(我不想为了得到有效的结果而打乱机器配置).
您可以在这里看到日光规则的枚举: Showing Transition Times