There is an error converting a DateTime in UTC to a DateTimeOffset type when the kind is Utc.
The origDateTime
comes from webservice so I don't have control of the content or format.
In most of the cases it comes with Kind=Unspecified
(even tough the time is in Utc) and then it's working, but in rare cases the Kind=Utc
and then the conversion to DateTimeOffset throws an exception:
"The UTC Offset for Utc DateTime instances must be 0. Parameter name: offset"
How should I solve this?
try {
//causees error !!!!
DateTime databaseUtcTime = DateTime.Parse("4/2/2016 6:25:20 PM");
var localTimeTemp = databaseUtcTime.ToLocalTime();
DateTime origDateTime = localTimeTemp.ToUniversalTime();
//this is working
//DateTime origDateTime = DateTime.Parse("4/2/2016 6:25:20 PM");
string timeZoneName = "Pacific Standard Time";
TimeZoneInfo localTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName);
DateTimeOffset localTime = new DateTimeOffset(origDateTime, localTimeZone.GetUtcOffset(origDateTime));
return localTime;
}
catch (Exception ex) {
string msg = ex.Message;
return null;
}
A few things:
If you really need to switch the Kind
of a DateTime
without adjusting its value, use DateTime.SpecifyKind
. It is cleaner than dealing with ticks. However, I don't think you really need to do this.
Don't use ToLocalTime
or ToUniversalTime
. Both of these will use the time zone setting of the server in the conversion process.
I'm not sure that your real code is actually parsing a string, because you indicated that it is coming from the database. If it's coming from the database, then no string parsing should be involved. Just do the following:
DateTime databaseUtcTime = (DateTime) yourDataReader["YourDataField"];
Once you have the input, you can then convert using the TimeZoneInfo.ConvertTime
functions. Your existing code doesn't correctly convert the time, it just assigns an offset without correctly adjusting the time value.
Since you wanted your output to be a datetimeoffset
, then the easiest way is to first convert your input datetime
to a datetimeoffset
with zero for the offset (since it comes from UTC).
DateTimeOffset dtoUtc = new DateTimeOffset(databaseUtcTime, TimeSpan.Zero);
Then it's fairly simple to convert:
string timeZoneName = "Pacific Standard Time";
TimeZoneInfo localTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName);
DateTimeOffset dtoLocal = TimeZoneInfo.ConvertTime(dtoUtc, localTimeZone);