Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Datetime conversion Adding 5 hours

Tags:

date

c#

datetime

I'm inserting records in the data table in c# where conversion of datetime is giving em extra 5 hours.

DateTime.ParseExact("2020-02-19T15:28:36.207Z", "yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture);

This gives me 8:28 pm instead of 3:28 pm Here is the response from c#

{2/19/2020 8:28:36 PM}
    Date: {2/19/2020 12:00:00 AM}
    Day: 19
    DayOfWeek: Wednesday
    DayOfYear: 50
    Hour: 20
    Kind: Local
    Millisecond: 207
    Minute: 28
    Month: 2
    Second: 36
    Ticks: 637177409162070000
    TimeOfDay: {20:28:36.2070000}
    Year: 2020```

like image 694
M Usama Alvi Avatar asked Jul 21 '26 16:07

M Usama Alvi


2 Answers

It's converting to local time. If you specify DateTimeStyles.AdjustToUniversal as a final argument, you'll end up with a value with a Kind of Universal and a time of 3:28pm:

var result = DateTime.ParseExact(
    "2020-02-19T15:28:36.207Z",
    "yyyy-MM-ddTHH:mm:ss.fffZ",
    CultureInfo.InvariantCulture,
    DateTimeStyles.AdjustToUniversal);

Note that the enum value name is somewhat unfortunate here, as you're not really adjusting - you're saying that you don't want an adjustment to local time. From the docs:

If the input string denotes a UTC time, through a time zone specifier or AssumeUniversal, no conversion occurs.

like image 138
Jon Skeet Avatar answered Jul 23 '26 04:07

Jon Skeet


The DateTime is formatted in ISO 8601 in UTC (with the "Z" suffix). Parsing it back in Roundtrip mode (DateTime.Parse("...", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind)) will automatically handle it correctly:

Strings that are passed to the Parse, TryParse, ParseExact, and TryParseExact methods of DateTime and DateTimeOffset can be parsed by using the "O" or "o" format specifier if they are in one of these formats. In the case of DateTime objects, the parsing overload that you call should also include a styles parameter with a value of DateTimeStyles.RoundtripKind. Note that if you call a parsing method with the custom format string that corresponds to the "O" or "o" format specifier, you won't get the same results as "O" or "o". This is because parsing methods that use a custom format string can't parse the string representation of date and time values that lack a time zone component or use "Z" to indicate UTC. [my emphasis]

What's going wrong in the code: By specifying "Z" as a character in your format string, you are matching the character "Z" literally (uppercase "Z" is not a custom format specifier), which leads to throwing away the time zone information and depending on the DateTimeStyles parameter to interpret the time zone. It's possible to pick the right value for this, but the better option is to use the round-trip format mode which already knows how to take care of this.

Edit: annoyingly, DateTime.ParseExact( datestr, "o", CultureInfo.InvariantCulture ) (parsing with "o") doesn't work, but parsing with the DateTimeStyles.RoundtripKind parameter does. Thanks to @SirRufo for pointing this out.

like image 40
Jesper Avatar answered Jul 23 '26 06:07

Jesper