I need to convert DateTime+TimeZoneInfo into DateTimeOffset.
How do I do this? I assume I have to pass TimeSpan but then I'm not sure if daylight saving times will be handled properly..
Thanks!
UPDATE
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time");
return new DateTimeOffset(DateTime.UtcNow, timeZone.BaseUtcOffset);
This code throws exception..
The UTC Offset for Utc DateTime instances must be 0.\r\nParameter name: offset
UPDATE 2
Sorry, I didn't realize that DateTimeOffset contains only offset, it doesn't contain actual zone information - so I'm accepting answer from @Dave as it is what I will be using..
DateTimeOffset reflects a time's offset from UTC, but it does not reflect the actual time zone to which that offset belongs. For details about time values and support for time zones, see Choosing Between DateTime, DateTimeOffset, TimeSpan, and TimeZoneInfo.
A DateTimeOffset value isn't tied to a particular time zone, but can originate from a variety of time zones. The following example lists the time zones to which a number of DateTimeOffset values (including a local Pacific Standard Time) can belong.
DateTime values lack any knowledge of time zone, or lack thereof. If you need to know when things actually occurred, with more precision than just the approximate date, and you can't be 100% sure that your dates are ALWAYS stored in UTC, then you should consider using DateTimeOffset to represent your datetime values.
You can also get the DATENAME(tz, @datetimeoffset) to get the offset as a varchar. TZOFFSET works in place of tz and, for what it's worth, is recognized by the SSMS syntax highlighter.
You should be about to get the difference between DateTime.UtcNow and DateTime.Now
var now = DateTime.Now;
var utcNow = now.ToUniversalTime();
var ts = utcNow - now;
If you are saving the offset, it is usually beneficial to save all dates in UTC (especially in a db) so you won't have to deal with offsets. You simply convert them before displaying but do all calculations in UTC.
Edit: If you have a TimeZone object, you can convert a UTC date to the local time for that time zone.
TimeZone.CurrentTimeZone.ToLocalTime()
OR
DateTime dt = TimeZoneInfo.ConvertTimeFromUtc()
Here's some sample code that will list a date in all timezones.
var dt = new DateTime(2011, 5, 21, 11, 0, 0);
foreach (var tzi in TimeZoneInfo.GetSystemTimeZones())
{
Console.WriteLine(string.Format("Time in {0} is {1}", tzi.DisplayName, TimeZoneInfo.ConvertTimeFromUtc(dt, tzi)));
}
TimeZoneInfo
has a BaseUtcOffset
property that is a TimeSpan
representing the offset.
This is the offset that the DateTimeOffset
constructors expects:
var myDTOffset = new DateTimeOffset(myDatetime, mytzInfo.BaseUtcOffset);
I think there may be an easier solution to eliminate the error. You tried:
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time");
return new DateTimeOffset(DateTime.UtcNow, timeZone.BaseUtcOffset);
DateTimeOffset throws an exception. What you wanted is this:
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time");
return new DateTimeOffset(DateTime.UtcNow).ToOffset(timeZone.BaseUtcOffset);
This will not throw the exception. I'm not sure why the constructor that accepts a TimeSpan even exists, since it only works if it matches the local or utc offset given in the DateTime object. But it is still possible with less headache.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With