Меня удивляет поведение TimeZoneInfo.IsValidTime (), поскольку оно не работает, как я ожидал, с недопустимым DateTime, установленным в качестве DateTimeKind.Local
[Fact]
public void DateTimeInvalidForTimeZone()
{
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
var testTimeUnspec = new DateTime(2020, 3, 29, 02, 01, 0, DateTimeKind.Unspecified);
var testTimeLocal = new DateTime(2020, 3, 29, 02, 01, 0, DateTimeKind.Local);
var testTimeUtc = new DateTime(2020, 3, 29, 02, 01, 0, DateTimeKind.Utc);
Assert.False(timeZone.IsInvalidTime(testTimeUtc)); //as anticipated - UTC so cannot be invalid
Assert.True(timeZone.IsInvalidTime(testTimeUnspec)); //as anticipated - the time is invalid
Assert.False(timeZone.IsInvalidTime(testTimeLocal)); //unexpected - the time is invalid
}
Примечание. Центральноевропейское стандартное время переходит в переход на летнее время 29 марта 2020 года в 02:00, поэтому временная последовательность по местному времени составляет 01:59:58, 01:59:59, 03:00:00, 03:00:01. Соответственно, все локальные времена между 02:00:00 и 02:59:59 являются недействительными.
Документация Microsoft объясняет:
- В случае DateTimeKind.Local и TimeZoneInfo, которые не являются локальными (т.е. отличаются от часового пояса компьютера) IsValidTime (DateTime) преобразует DateTime во время объекта TimeZoneInfo и возвращает false.
Это говорит о том, что объекты DateTime, которые являются DateTimeKind.Local, всегда будут действительными, что не то, что я ожидаю или хочу. Кто-нибудь может объяснить логику c за реализацией Microsoft? Еще одна причина рассмотреть Nodatime?