我对臭名昭着的夏令时有疑问。
我有一个数据点列表,一年中每小时一个。要检查是否存在所有数据点,我创建一个这样的时间迭代器:
DateTime timeIterator = new DateTime(year, 1, 1, 0, 0, 0);
用
迭代它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是有效的时间点,我如何检查?
提前致谢,
弗兰克
答案 0 :(得分:2)
如果我的DateTime是有效的时间点,我如何检查?
不要检查,确保它。您可以按UTC计算小时数,并将每个点转换为当地时间。
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或显式偏移)存储数据,以便以后进行比较。
修改强>
如果您的数据时区有一个有效的TimeZoneInfo
对象,并且由于某种原因您不想切换到DateTimeOffset
,您还可以使用以下功能:< / p>
TimeZoneInfo tzi = /* the timezone */;
DateTime timeIterator = /* the time */;
if (tzi.IsAmbiguousTime(timeIterator))
{
/* Expect multiple data entries */
}
if (tzi.IsInvalidTime(timeIterator))
{
/* Expect no data entries */
}
答案 1 :(得分:0)
我也遇到了时区问题。 我建议你将日期保存为UTC值
然后转换它:(可能使用扩展方法)
private DateTime TransformToTimezone(DateTime datetime)
{
TimeZoneInfo beZone = TimeZoneInfo.FindSystemTimeZoneById("Romance Standard Time");
//Convert to timezone
return TimeZoneInfo.ConvertTimeFromUtc(datetime, beZone);
}