5

我正在开发为 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 的最佳方法是什么?

4

4 回答 4

4

您的数据库中有垃圾,3/10/2013 2:02:11 AM 从未存在过。那天早上 1:59 之后的一分钟是凌晨 3:00,时钟移动了一个小时。.NET 不会容忍那个垃圾日期。

您将需要找出垃圾时间戳是如何在您的数据库中结束的。显然,无视夏令时规则的时间从一个时区转换为另一个时区,例如在一个时区活动但在另一个时区不活动,很可能是垃圾的来源。如果您无法修复您的 dbase 以使用 UTC,那么至少在您的代码中执行此操作。首先在一个时区使用 UTC,然后在另一个时区返回本地时间。使用 TimeZoneInfo 类、ConvertTimeFrom/ToUtc 方法。

于 2013-03-18T17:55:59.697 回答
3

我遇到了这个问题。我通过添加一个新的 GMT 时间列来修复它。这允许应用程序使用原始数据和任何与 GMT 一起使用的修复程序。然后我更改了应用程序,以便任何有夏令时问题的代码都可以访问这个新列。此外,随着时间的推移,我将任何用于计算的代码重新指向这个新列,让显示器与旧列一起工作。它并不优雅,但它可以工作并且很容易。

于 2013-03-18T17:48:42.940 回答
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 示范

于 2013-03-18T18:29:43.043 回答
1

如果可能的话,我会遵循其他答案之一 - 你想正确解决这个问题。如果您在秋季过渡期间的时间不正确,则不会产生异常,只会随机休息一个小时。

有一种解决方法可以让您摆脱当前的困境。由于只有春季期间缺少的一小时会导致异常,因此您可以捕获异常并在重复转换之前添加一个小时。

于 2013-03-18T21:04:06.763 回答