Home > Enterprise >  C# Datetime ISO 8601 format gives incorrect value
C# Datetime ISO 8601 format gives incorrect value

Time:02-03

I am attempting to get a correctly formatted ISO 8601 date, and I keep hitting issues. My initial code seemed to be working, but I found that DST dates were not returning as expected. I made a .NET fiddle to ask about this issue here on stackoverflow, but it seems the way the "system" timezone works is going to cause me further problems when I deploy my code.

Here is a dotnet fiddle that displays something completely wrong:

using System;
                
public class Program
{
    public static void Main()
    {
        var val3 = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(2021, 10, 13, 18, 0, 0), TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"));
        Console.WriteLine(val3.ToString("yyyy-MM-ddTHH:mm:sszzz"));
    
    }
}

If I run this, I get the following:

2021-10-13T13:00:00 00:00

So the time is correct for CST, but the offset looks like it is reflecting the "system" timezone on the server. Taken altogether, the date is completely different than the input date.

If I run this code on my development system where the local timezone is CST, I get yet another different answer:

2021-10-13T08:00:00-06:00

Given that the date in question was in DST, I expect both of the above to return the following:

2021-10-13T13:00:00-05:00

What I am doing wrong?

CodePudding user response:

In the DateTime constructor, can you check what you get when you specify the DateTimeKind.Utc value in the last parameter ?

Maybe it is because of the Daylight Saving Time that is not considered in the calculation.

Also check this site to help you with the calculation: https://www.timeanddate.com/worldclock/converter.html?iso=20220203T180000&p1=1440&p2=tz_cst

CodePudding user response:

Let me see if my understanding is correct (I'm still not entirely sure when the SOAP comes into play in the question).

You have a UTC DateTime:

var dt = new DateTime(2021, 10, 13, 18, 0, 0, DateTimeKind.Utc);

And you'd like to format that in CST -- which, on October 13, is actually CDT (-05:00)?

If that is correct, then you want to utilise DateTimeOffset, which has a better understanding of.. well, time offsets.

// Your original value. This will have an offset of "00:00" 
// as the DateTime above was created as `DateTimeKind.Utc`
var timeAtUtc = new DateTimeOffset(dt);

// Alternatively:
// var timeAtUtc = new DateTimeOffset(2021, 10, 13, 18, 0, 0, TimeSpan.Zero);

// Find out the correct offset on that day (-5:00)
var cstOffsetAtTheTime = TimeZoneInfo
    .FindSystemTimeZoneById("Central Standard Time")
    .GetUtcOffset(timeAtUtc);

// And now apply the offset to your original value
var timeAtCst = timeAtUtc.ToOffset(cstOffsetAtTheTime);

// You will now get "2021-10-13T13:00:00-05:00" 
// no matter where you run this from.
Console.WriteLine(timeAtCst.ToString("yyyy-MM-ddTHH:mm:sszzz"));

// Edit: If you pass it a date in Feb, you'll see that it will correctly be at -06:00.

  •  Tags:  
  • Related