I have code that converts long numbers to dates.
DateTimeOffset value =
DateTimeOffset.FromUnixTimeSeconds(1597325462);
DateTime showTime = value.DateTime;
string easternZoneId = "America/New_York";
TimeZoneInfo easternZone =
TimeZoneInfo.FindSystemTimeZoneById(easternZoneId);
DateTime targetTime =
TimeZoneInfo.ConvertTime(showTime, easternZone);
Console.WriteLine("DateTime is {0}", targetTime);
On my Mac, the output is "DateTime is 8/13/2020 6:31:02 AM"
On my server the output is "DateTime is 8/13/2020 9:31:02 AM"
Identical code on both.
The Linux box value is accurate. How can I get the same result on my Mac?
2
Answers
The issue seems to be that there is not such a timezone I’d in the ICU library that both OS look into.
Check the example in the Microsoft docs:
https://learn.microsoft.com/en-us/dotnet/api/system.timezoneinfo.converttimebysystemtimezoneid?view=netcore-3.1
So it looks like the id you should look for is ""Eastern Standard Time"
If you can’t find it then run the following code to check the available timezones on your pc
So check the timezones and copy the correct string to use based on what exists on the machine.
The overload of
TimeZone.ConvertTime
you’re using takes aDateTime
value and a destinationTimeZoneInfo
. There’s no mention of the source time zone, so it is infered from the.Kind
property of theDateTime
being passed in.In your case, that is
DateTimeKind.Unspecified
, because the.DateTime
property of aDateTimeOffset
always returns unspecified, regardless of what the offset is.In the
ConvertTime
call, if the kind isDateTimeKind.Unspecified
, it is assumed to be local time (as if it wereDateTimeKind.Local
). (Scroll down to the Remarks section in the docs here.) Thus, you are converting as if the Unix timestamp were local-time based, rather than the actuality that it is UTC based. You get different results between your workstation and server because they have different system-local time zones – not because they are running different operating systems.There are a number of different ways to rewrite this to address the problem. I will give you a few to choose from, in order of my preference:
You could leave everything as a
DateTimeOffset
throughout the conversion process:You could use the
.UtcDateTime
property instead of the.DateTime
property:You could use
ConvertTimeFromUtc
instead ofConvertTime
:You could specify UTC as the source time zone in the
ConvertTime
call:There are a few other options, such as explicitly setting the kind, but I think the above gives you enough to go on.
If in doubt, pick the first option.
DateTimeOffset
is much easier to rationalize thanDateTime
in most cases.