Reputation: 303
My app gets a DateTime object in UTC and needs to output as a string it in EST format. I've tried the following code, but when I get the output the offset still shows as +00:00 instead of -05:00
static void Main(string[] args)
{
var currentDate = DateTime.Now.ToUniversalTime();
var convertedTime = ConvertUtcToEasternStandard(currentDate);
Console.WriteLine(currentDate.ToString("yyyy-MM-ddTHH:mm:sszzz"));
Console.WriteLine(convertedTime.ToString("yyyy-MM-ddTHH:mm:sszzz"));
}
private static DateTime ConvertUtcToEasternStandard(DateTime dateTime)
{
var easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
return TimeZoneInfo.ConvertTimeFromUtc(dateTime, easternZone);
}
This outputs:
2016-11-18T06:56:14+00:00
2016-11-18T01:56:14+00:00
So the time is being shifted correctly, but the offset stays at +00:00 when I want it to be -05:00. Any idea how I can get a DateTime object with the correct offset when output with the above format string?
Upvotes: 1
Views: 6128
Reputation: 5953
I read this in the API not long ago, basically, with DateTime
values, it's very much impossible to get the zzz
format offset to be something useful.
With DateTime values, the "zzz" custom format specifier represents the signed offset of the local operating system's time zone from UTC, measured in hours and minutes. It does not reflect the value of an instance's DateTime.Kind property. For this reason, the "zzz" format specifier is not recommended for use with DateTime values.
With DateTimeOffset values, this format specifier represents the DateTimeOffset value's offset from UTC in hours and minutes.
The offset is always displayed with a leading sign. A plus sign (+) indicates hours ahead of UTC, and a minus sign (-) indicates hours behind UTC. A single-digit offset is formatted with a leading zero.
For example, I'm in Eastern Standard Time, and this is my result:
2016-11-18T07:9:38-05:00
2016-11-18T02:9:38-05:00
Obviously UTC time shouldn't have an offset of -05:00
.
Modify your code just a bit and we have a solution:
void Main()
{
var currentDate = DateTimeOffset.Now.ToUniversalTime();
var convertedTime = ConvertUtcToEasternStandard(currentDate);
var format = "yyyy-MM-ddTHH:m:sszzz";
Console.WriteLine(currentDate.ToString(format));
Console.WriteLine(convertedTime.ToString(format));
}
// Define other methods and classes here
private static DateTimeOffset ConvertUtcToEasternStandard(DateTimeOffset dateTime)
{
var easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
return TimeZoneInfo.ConvertTime(dateTime, easternZone);
}
Result:
2016-11-18T07:17:46+00:00
2016-11-18T02:17:46-05:00
That's more like it.
Note: replaced previous code, ignorance got the best of me and I failed to realize that it wasn't working right. TimeZoneInfo.ConvertTime
takes a DateTimeOffset
which does what we want.
And if we add another case for Pacific Standard Time
:
private static DateTimeOffset ConvertUtcToPacificStandard(DateTimeOffset dateTime)
{
var pacificZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
return TimeZoneInfo.ConvertTime(dateTime, pacificZone);
}
We get the correct result:
2016-11-17T23:21:21-08:00
Upvotes: 3