I've got a problem with the Italian Daylight Saving Time. Converting the unix 687481200000 in .NET looks unpredictable (sure I'm missing something).
As you can see typing in your browser console:
console.log(new Date(687481200000).toLocaleString('it-IT', {timeZone: 'Europe/Rome', timeZoneName: 'short'}));
the unix timestamp value of 687481200000 should return the italian date 1991-10-15 00:00:00 (in Italy the date is typed 15/10/1991 but we are always talking about 15 October).
Now I want you to take a look at this snippet
https://dotnetfiddle.net/jKShoE
When I run it in the browser using Compiler: .NET 6 I get
Data e ora italiane: 10/15/1991 00:00:00
changing the Compiler to .NET 4.7.2
https://dotnetfiddle.net/GV7FYD
I got
Data e ora italiane: 10/15/1991 1:00:00 AM
And If I copy that code in a new .NET 6 project in visual studio 2022
Data e ora italiane: 15/10/1991 01:00:00
Someone can explain me why? Is there a way to get the correct hour 00:00:00 without using external libraries (like NodaTime)?
Ps: working on Windows 10.0.19045 Build 19045, Italian localization
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
I had to dig deeper and found more answers once I searched for TimeZoneInfo.AdjustmentRule on 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); // I got 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
}
}
I am still not clear on how and who manages the time zone database, whether it's the operating system or the .NET framework, but it seems to me that this configuration is complex enough to make me opt for the use of NodaTime (I don't want to mess with the machine configuration in order to get valid results).
You can see the enumeration of the daylight rules here: Showing Transition Times
It'a a matter of daylight time:
In .Net 6 : https://dotnetfiddle.net/qP1icN
Daylight : False
Data e ora italiane: 10/15/1991 00:00:00
In .Net 4.7.2 : https://dotnetfiddle.net/7eBu3y
Daylight : True
Data e ora italiane: 10/15/1991 1:00:00 AM
People get paid to handle this kind of problem worldwide...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With