Hassan Ali
Hassan Ali

Reputation: 71

TimeZoneInfo.ConvertTime method not converting the DateTime correctly

I have the following date string: 2015-11-10T23:52:18.5245011Z
And when I parse it using DateTime.Parse method it returns 11/11/2015 10:52:18 AM which is incorrect.

I also tried the follwing conversion:

TimeZoneInfo est = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time");
DateTime targetTimeUtcconverted = TimeZoneInfo.ConvertTime(UtcDate, est);

and it still gives out: 11/11/2015 10:52:18 AM

Can't figure out what I am missing here.

Upvotes: 0

Views: 1569

Answers (1)

Matt Johnson-Pint
Matt Johnson-Pint

Reputation: 241808

Use:

DateTime.Parse(s, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind)

Or:

DateTime.Parse(s, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal)

Or (best option):

DateTimeOffset.Parse(s)

By default, DateTime.Parse will adjust to local time if there is any offset information present in the string. Since Z is the same as +00:00, it assumes the input is +00:00, then adjusts from UTC to the local time zone.

If there is no offset information present, it returns a DateTime with Unspecified kind.

Passing DateTimeStyles.RoundtripKind tells it to treat any value with an offset as local time (as before), but any value containing Z, UTC, GMT, etc. to have DateTimeKind.Utc.

Passing DateTimeStyles.AdjustToUniversal tells it that the output should always have DateTimeKind.Utc, and the value should be adjusted if necessary.

Parsing using DateTimeOffset.Parse bypasses all of that convoluted behavior and just returns a value with an offset matching what was provided. This is the best approach when an offset (or Z) is present in the input string. If you need a DateTime, you can use the UtcDateTime, LocalDateTime, or DateTime properties from the resulting DateTimeOffset.

The time zone conversion code you gave is correct, as long as the Kind is UTC. It would be more explicit to use ConvertTimeFromUtc, but that wouldn't really matter in this case. The best approach is to use the overload of ConvertTime that works with DateTimeOffset values. The resulting value will be a DateTimeOffset whose DateTime property matches the time in that time zone, and whose Offset property is the correct offset for that time in that time zone.

Upvotes: 1

Related Questions