GThree
GThree

Reputation: 3502

How to get the offset when converting time to specific timezone and then UTC? C#

I am trying to convert date to UTC format where I can get correct offset. I am using ToString("O") in simple DateTime.Now which works.

Now when I am converting my current time (EST) to CST (Central) or MST (Mountain) then I am not getting offset. What am I missing here? Is there any other way to do it?

Code:

var currentTimeToUtc = DateTime.Now.ToString("O");
// Output = "2018-12-27T12:31:21.9946661-05:00" --This is perfect.

var centralTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.Now, "Central Standard Time");
var centralTimeToUtc = centralTime.ToString("O");
// Output = "2018-12-27T11:31:19.8046052"
// Expected Output = "2018-12-27T11:31:19.8046052-06:00"

var mountainTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.Now, "Mountain Standard Time");
var mountainTimeToUtc = mountainTime.ToString("O");
// Output = "2018-12-27T10:31:25.2438418"
// Expected Output = "2018-12-27T10:31:25.2438418-07:00"

Upvotes: 3

Views: 960

Answers (1)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726499

This is the expected behavior of DateTime. If you need to keep time zone information, use DateTimeOffset instead.

The reason for the difference in the output is that DateTime.Now and centralTime / mountainTime are of different kind: DateTime before conversion is Local, but after conversion it becomes Unspecified.

Run the program below to confirm this:

var now = DateTime.Now;
Console.WriteLine(now.Kind);
var centralTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(now, "Central Standard Time");
Console.WriteLine(centralTime.Kind);
var mountainTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(now, "Mountain Standard Time");
Console.WriteLine(mountainTime.Kind);

The behavior cannot be changed because DateTime does not store offset; it relies on two well-known offsets for interpretation of the time zone - Local means your local time zone, and UTC means UTC time zone.

The third option, Unspecified, means that the value of DateTime cannot be interpreted as an absolute value by itself, because time zone has been stripped from it. Your code knows what time zone it is, because you did the conversion, but the information about the time zone is part of your program's design, not part of the corresponding DateTime object. .NET added DateTimeOffset objects specifically to address this problem.

Upvotes: 6

Related Questions