Daylight saving and DateTime.AddHour()
臭名昭着的夏令时我有一个问题。
我有一个数据点列表,一年中每小时一个。 要检查是否存在所有数据点,我创建一个这样的时间迭代器:
1 |
迭代它
1 | timeIterator = timeIterator.AddHours(1); |
如果列表中存在时间点,则检查每次迭代。
遇到夏令时时会出现问题。 我是2014年的例子,时钟在0200年3月30日从0300移动到0300.所以,在0159到0300之后。但是DateTime.AddHours()完全忽略了夏令时。 如果timeIterator在{30.03.2014 01:00:00}并且我调用AddHours(1),我得到{30.03.2014 02:00:00},这显然不存在。
如果我现在测试该数据点的列表,它(自然)不在列表中,我抛出一个错误的"缺少数据点错误"。
如果我的DateTime是有效的时间点,我如何检查?
提前致谢,
坦率
How can I check, if my DateTime is a valid point in time?
不要检查,确保它。您可以计算UTC的小时数,并将每个点转换为当地时间。
1 2 3 4 5 6 7 | DateTimeOffset timeIterator = new DateTimeOffset(new DateTime(year, 1, 1, 0, 0, 0, DateTimeKind.Local)); timeIterator = timeIterator.AddHours(1); timeIterator.LocalDateTime; // assuming you have a TimeZoneInfo object, you can also get different local times: TimeZoneInfo tzi = /* the timezone */; TimeZoneInfo.ConvertTimeFromUtc(timeIterator.UtcDateTime, tzi); |
但是,正如Damien_The_Unbeliever评论的那样,这只解决了问题的一部分,程序将不再检查无效日期的存在。当您的数据以本地时间存储时,会出现另一个问题。这意味着从DST到正常时间的转换将具有两个连续的小时,具有相同的本地DateTime表示。为了避免这种情况,必须使用完整信息(UTC或显式偏移)存储数据,以便以后进行比较。
编辑:
如果您的数据时区有一个有效的
1 2 3 4 5 6 7 8 9 10 | TimeZoneInfo tzi = /* the timezone */; DateTime timeIterator = /* the time */; if (tzi.IsAmbiguousTime(timeIterator)) { /* Expect multiple data entries */ } if (tzi.IsInvalidTime(timeIterator)) { /* Expect no data entries */ } |
我也遇到过时区问题。
我建议你将日期保存为UTC值
然后转换它:(也许使用扩展方法)
1 2 3 4 5 6 7 | private DateTime TransformToTimezone(DateTime datetime) { TimeZoneInfo beZone = TimeZoneInfo.FindSystemTimeZoneById("Romance Standard Time"); //Convert to timezone return TimeZoneInfo.ConvertTimeFromUtc(datetime, beZone); } |