我正在开发运行24/7/365运行GPS设备报告的软件。部分报告输出要求我们将存储的数据库时间(保存在中央标准时间)转换为用户计时器(任何请求的时区)。我们每年两次遇到DST问题,当时人们运行的报告在时间变化之前开始并在时间变化之后结束。它失败了一行:
return TimeZoneInfo.ConvertTime(dateToConvert, DatabaseTime, UserTime);
dateToConvert
是要转换的DateTime
。 DatabaseTime
和UserTime
都是TimeZoneInfo
个对象。我没有做任何棘手或复杂的事情,但DST时间附近的DateTimes改变抛出异常。例如3/10/2013 2:02:11 AM
,即使它正在从中央时间“转换”到中部时间。
在DST时间变化附近处理DateTimes的最佳方法是什么?
答案 0 :(得分:4)
您的数据库中有垃圾,3/10/2013 2:02:11 AM从未存在过。那天早上凌晨1点59分是凌晨3点,时钟被移动了一个小时。 .NET不会忍受这个垃圾日期。
您需要了解垃圾时间戳在dbase中的结果。显然,从一个时区到另一个时区的时间转换忽视了夏令时规则,例如活动在一个时间而不是另一个时,很可能是垃圾的来源。如果您无法修复dbase以使用UTC,那么至少在您的代码中执行此操作。首先在一个时区中转到UTC,然后在另一个时区回到当地时间。使用TimeZoneInfo类,ConvertTimeFrom / ToUtc方法。
答案 1 :(得分:3)
我遇到了这个问题。我通过添加新的GMT时间列来修复它。这允许应用程序使用原始数据和任何修复程序来使用GMT。然后我更改了应用程序,以便任何遇到夏令时问题的代码都可以访问这个新列。此外,随着时间的推移,我将用于计算的任何代码重新指向此新列,使显示与旧列一起使用。它并不优雅,但它很有效,很容易。
答案 2 :(得分:1)
转换应该正常工作,因为时间不是真正的垃圾,正如汉斯所说,而是它只是没有调整(我刚刚发明的一个术语)。 3/10/2013 2:02:11 AM CDT == 3/10/2013 8:02:11 AM UTC == 3/10/2013 3:02:11 AM CDT
...它们在语义上都是等价的。如果您不相信我,请在timeanddate.com进行转换,看看它们都是等同的(尽管它们的计算器为最接近的5分钟)。 .NET代码是否允许这种语义等价,我没有尝试过,因为我目前不在我的开发框前面。
更新#1:
在设置为CST时区的计算机上运行以下代码:
using System;
namespace TimeZoneSample
{
public static class Program
{
public static void Main()
{
DateTime t = DateTime.Parse("3/10/2013 2:02:11 AM");
Console.WriteLine(t);
Console.WriteLine(t.ToUniversalTime());
Console.WriteLine(t.ToUniversalTime().ToLocalTime());
}
}
}
这会产生以下控制台输出:
3/10/2013 2:02:11 AM
3/10/2013 8:02:11 AM
3/10/2013 3:02:11 AM
证明我的原始解释是正确的。 quod erat demonstrandum
答案 3 :(得分:1)
如果可能的话,我会遵循其他一个答案 - 你想要妥善解决这个问题。如果在秋季过渡期间您的时间不正确,则不会产生异常,它只会随机一小时。
有一种解决方法可以帮助您摆脱目前的阻塞。由于它只是在春季中导致异常的缺失时间,因此您可以捕获异常并在重复转换之前添加一小时。