I have to plot a dataset over time which I calculate from a short array. This works but when it comes to converting to the correct time zone it throws an exception:
System.ArgumentException: "The supplied DateTime represents an invalid time. For example, when the clock is adjusted forward, any time in the period that is skipped is invalid. Parameter name: dateTime"
The problem is that the dataset was recorded during time shift to daylight saving time, so there is a gap between 2 and 3 AM. From 2 AM on, the times are invalid because they simply do not exist. But when I try to include an if statement to prove on invalid times it does not help because the bool "isvalid" is always false. I don't get why the bool stays false although a few lines later it throws an exception that this DateTime is invalid, so what can I do? Thanks for helping!
Additional information: The Kind
of date_0 is Local
.
DateTime date_0; //equals {29.03.2020 02:00:00} which is invalid
TimeZoneInfo tzf = TimeZoneInfo.FindSystemTimeZoneById("Central Europe Standard Time");
bool isInvalid = tzf.IsInvalidTime(date_0);
if (isInvalid)
{
//do something (but this is never reached)
}
DateTime dt = TimeZoneInfo.ConvertTime(date_0, tzf); //here the exception is thrown
var isSum = tzf.IsDaylightSavingTime(dt);
if (isSum) date_0 = date_0.AddHours(1);
Solution
Thanks for the helpful comments. The problem was that the Kind
of date_0 was different to the TimeZoneInfo
tzf. I resolved it by just changing tzf to Local
which corresponds to date_0. Now the invalid DateTime
is recognized and further steps can be done.
TimeZoneInfo tzf = TimeZoneInfo.Local;
if(tzf.IsInvalidTime(date_0))
{
// ...
}
I assume that your DateTime
has a Kind
of Unspecified
. From the online documentation
IsInvalidTime would then assume "dateTime is the time of the TimeZoneInfo object and determines whether it is invalid".
Whereas ConvertTime says "Assumed to be Local. Converts the local time to the time in destinationTimeZone."
So if your Local timezone is not the same as your TimeZoneInfo, the result will be surprising.
If your DateTime.Kind
is Local, but your TimeZoneInfo is not local then the documentation suggests that IsInvalidTime will "Converts dateTime to the time of the TimeZoneInfo object and returns false." Which is what the source code does. What's the point of a function that always returns false?
Since it looks like you are processing datetimes that are neither Local nor UTC, you should convert to DateTimeOffset
, or just convert everything to UTC.
date_0 = DateTime.SpecifyKind(date_0, DateTimeKind.Unspecified);
if (tzf.IsInvalidTime(date_0)){
// ...
}
var dto = new DateTimeOffset(date_0, tzf.GetUtcOffset(date_0));