What you refer to as "double precision date and time value" is also known as an "OLE Automation Date", or an "OADate" for short.
OADates do not convey any time zone information. They are just a point since December 30th 1899 in some unknown calendar. Additionally, there are some strange quirks about how they are encoded (see the remarks in these MSDN docs) that make them slightly undesirable. I would avoid them if at all possible.
Nonetheless, you should always treat them as unspecified. In fact, the FromOADate
method you're calling already returns it as Unspecified
kind, so there's no reason to call DateTime.SpecifyKind
at all. In short, your function should simply be:
public double ConvertTime(double inTime, string sourceTZ, string destTZ)
{
DateTime sourceDT = DateTime.FromOADate(inTime);
TimeZoneInfo sourceTZI = TimeZoneInfo.FindSystemTimeZoneById(sourceTZ);
TimeZoneInfo destTZI = TimeZoneInfo.FindSystemTimeZoneById(destTZ);
DateTime destDT = TimeZoneInfo.ConvertTime(sourceDT, sourceTZI, destTZI);
return destDT.ToOADate();
}
However, if your use case calls for assuming that the input time is the computer's local time zone, then you would create a different method instead:
public double ConvertFromLocalTime(double inTime, string destTZ)
{
DateTime sourceDT = DateTime.FromOADate(inTime);
TimeZoneInfo sourceTZI = TimeZoneInfo.Local;
TimeZoneInfo destTZI = TimeZoneInfo.FindSystemTimeZoneById(destTZ);
DateTime destDT = TimeZoneInfo.ConvertTime(sourceDT, sourceTZI, destTZI);
return destDT.ToOADate();
}
You still do not need to specify the local kind, because when an unspecified DateTime
is passed to TimeZoneInfo.ConvertTime
it assumes that value is in terms of the source time zone - which is your local time zone in this case. While a local kind would work here, it's not required.
As to why you got the error when trying local kind, I assume this was the error you had:
"The conversion could not be completed because the supplied DateTime did not have the Kind property set correctly. For example, when the Kind property is DateTimeKind.Local, the source time zone must be TimeZoneInfo.Local."
As the error explains, you can't pass in a DateTime
with local kind to TimeZoneInfo.ConvertTime
unless the source timezone is specifically taken from DateTimeKind.Local
.
It's not enough that the source time zone ID matches the local time zone ID, because TimeZoneInfo.Local
has a special case of taking into account the "Automatically adjust clock for Daylight Saving Time" option. See these MSDN docs for details. In other words:
TimeZoneInfo.Local != TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id)
Lastly, I think you misunderstand DateTimeKind
. You said:
Surely for the time to be converted properly it is necessary to specify that the value is a local time and belongs to a certain timezone?
The "local" in DateTimeKind.Local
and in TimeZoneInfo.Local
specifically means local to the computer where the code is running. It's not a local zone, it's the local zone. If the DateTime
is tied to some other time zone than UTC or the computer's own local time zone setting, then DateTimeKind.Unspecified
is used.