.net在夏天dst增加了一个小时

时间:2015-01-12 14:56:18

标签: c# .net web-services dst

我从网络服务2013-10-15T12:54:18+01:00获取以下字符串。这个日期是在夏天夏令时和我的.NET代码(我认为是Web服务代理)自动添加一个小时。如果返回值随冬季夏令时降低,则情况并非如此。返回的时间(12:54:18)是我想要显示的内容,我不想进行任何类型的重新计算。

我使用TimeSpan DateTime.TimeOfDay来显示时间。

我能做些什么来实现它?

3 个答案:

答案 0 :(得分:3)

我正在尝试将您的问题和其他评论中的各个部分放在一起。到目前为止,这是我的分析:

  1. 在线上你会看到两个不同的日期和时间字符串:

    • 没有夏令时(冬天),字符串为2013-12-30T12:54:18

    • 夏令时(夏令时)字符串为2013-10-15T12:54:18+01:00

    这表示网络服务使用 GMT标准时间作为时区。

  2. 您想从日期和时间字符串中提取GMT时间戳。

  3. 但是,在您和Web服务之间有一些未指定的 Web服务代理(我假设某种.NET框架?),在您的代码中,您只能访问{ {1}}此外,您的代码正在中欧标准时间时区执行,如果我们忽略过渡时间的短暂时间,那么在夏季和冬季基本上比GMT提前一小时从夏令时开始。

  4. 我希望到目前为止我是正确的。

    您可以使用以下代码将传入的DateTime转换为GMT:

    DateTime

    此示例在夏令时期间给出正确答案。传入的日期和时间字符串包含偏移量,并正确解析为本地时区(CET)。 // Framework code creates the DateTime. var sourceDateTime = DateTime.Parse("2013-10-15T12:54:18+01:00"); // Application code can further process the DateTime. var destinationTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time"); var destinationDateTime = TimeZoneInfo.ConvertTime(sourceDateTime, destinationTimeZoneInfo); 假定源TimeZoneInfo.ConvertTime位于本地时区且结果正确。

    然而,代码在冬季没有夏令时失败:

    DateTime

    请注意,日期和时间字符串不再包含时区偏移量。偏移量为var sourceDateTime = DateTime.Parse("2013-12-30T12:54:18"); ,但由于某种原因,字符串中缺少该偏移量。这意味着假定源+00:00位于本地时区(CET)而不是从实际时区(GMT)转​​换。 如果我的分析正确,这就是问题的根源。

    另一种解释方式:

           | Server (GMT)  | Framework (CET)           | My code
    -------+---------------+---------------------------+----------------------------
    Summer | +01:00 suffix | GMT -> CET adds 1 hour    | CET -> GMT subtracts 1 hour
    -------+---------------+---------------------------+----------------------------
    Winter | No suffix     | Assumed to be CET         | CET -> GMT subtracts 1 hour
    
    

    这个问题没有简单的解决办法。如果您可以说服Web服务提供正确的偏移量,即使它是DateTime,我的代码将在夏季和冬季都有效。更好的是,仅使用UTC并且仅在最终用户参与时转换为本地时间。但我想你无法控制网络服务?

    一种选择是在与服务器相同的时区执行代码(例如GMT)。然后你应该可以直接使用时间戳而无需任何转换。

    另一个更丑陋的选择是确定Web服务是否在夏令时之外,然后相应地调整时间:

    +00:00

    我试图尽可能保持代码的一般性,但实际上它只是试图修复缺少var destinationTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time"); if (!destinationTimeZoneInfo.IsDaylightSavingTime(sourceDateTime)) { var sourceDateTimeOffset = new DateTimeOffset(sourceDateTime, destinationTimeZoneInfo.BaseUtcOffset); sourceDateTime = sourceDateTimeOffset.UtcDateTime; } var destinationDateTime = TimeZoneInfo.ConvertTime(sourceDateTime, destinationTimeZoneInfo); 的情况,在这种情况下+00:00正好是0所以它可能略微过度杀伤这样做。

    更重要的是,我不确定此代码是否会在夏令时转换期间提供正确的结果。尽管我认为同一时间的格林尼治标准时间和CET过渡仍然比格林威治标准时间提前一小时。您必须创建一些单元测试以确保获得所需的结果。

答案 1 :(得分:2)

在这种示例中,DateTime对象不包含偏移量。它只保存一个kind,即:本地偏移量(运行时环境的偏移量)或UTC。这样做,因为DateTimeOffset是你想要的:

DateTimeOffset test = DateTimeOffset.Parse("2013-10-15T12:54:18+01:00");

Console.WriteLine(test.DateTime.TimeOfDay); // UTC
Console.WriteLine(test.LocalDateTime.TimeOfDay); // Localized with the offset parsed

将输出

12:54:18
11:54:18

答案 2 :(得分:1)

您可能需要查看this MSDN article,其中描述了TimeOfDay当前返回的转换。

通过检查该文章,您可以找到如何纠正它的方法。 TimeZoneInfo是您需要的类。

编辑,Jon Skeet提供的工作也可以提供帮助,请查看Noda Time blogspot以获取更多信息!