Q:

C# DateTime.ToString "o" Format Returns Different String on Azure

I have a scenario in which I want to turn UTC dates into ISO 8601 strings with a certain timezone to send down via web api. The recommended way to do this is to use TimeZoneInfo like so:
var configuredTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneString);
var localTime = DateTime.SpecifyKind(TimeZoneInfo.ConvertTimeFromUtc(utcTime, configuredTimeZone), DateTimeKind.Local);
var stringResult = localTime.ToString("o");

This works fine on my local machine, but I'm running into a very weird situation where ToString outputs a different string when the code is hosted in an Azure web app. Locally I get 2017-02-20T00:00:00-06:00 (which is what I want, as it contains the timezone info I need), but when hosted in Azure I get 2017-02-20T00:00:00+00:00.(which is in UTC, not what I want). Since I am manually applying the time zone I want, I am not sure why the format is appending the wrong timezone information. Has anyone run into this before?

A:

As has been mentioned in the comments, System.DateTime cannot store time zones. All it knows is "local" or "UTC". Being hosted in Azure, its "local" time is UTC.
So your statement of TimeZoneInfo.ConvertTimeFromUtc(utcTime, configuredTimeZone) would convert the UTC time to your time (midnight of the 20th), but because DateTime holds no timezone, it is of DateTimeKind.Unspecified. Your DateTime.SpecifyKind(...,  DateTimeKind.Local) simply tells it that it is of type "local", and in the case of an Azure host, UTC+00:00.
If timezones are important, you want to utilise System.DateTimeOffset instead of DateTime. It is specifically built for holding and manipulating (as its name implies) timezone offsets.

