Datetime隐式转换为Datetimeoffset导致错误的偏移?

时间:2015-12-07 09:16:55

标签: datetime timezone dst timezone-offset datetimeoffset

在尝试确定给定的datetimeoffset是否发生在timezoneadjustment(夏令时)的开头或结尾时,我注意到了一些奇怪的事情。 而且我不确定我是否会以错误的方式解决这个问题。

以下面的代码为例:

class Program
{
    static void Main(string[] args)
    {
        // Note: this is done on a swedish computer.
        int year = 2015;
        DateTimeOffset dateTimeJustBeforeOffsetChanges = new DateTime(year, 10, 25, 1, 59, 59);
        DateTimeOffset dateTimeRightWhenOffsetChanges = new DateTime(year, 10, 25, 2, 0, 0); // 2015-10-25 02:00:00. This is how we set our offset. We let the implicit conversion do all the work :)

        var daylightSavings = TimeZone.CurrentTimeZone.GetDaylightChanges(year);

        Console.WriteLine(dateTimeJustBeforeOffsetChanges); // Prints out 2015-10-25 01:59:59 +02:00
        Console.WriteLine(dateTimeRightWhenOffsetChanges); // Prints out 2015-10-25 02:00:00 +01:00 This is the exact time when the datetimeoffset starts using offset +02 instead of +01
        Console.WriteLine(daylightSavings.End.ToString()); // Prints out 2015-10-25 03:00:00
        Console.ReadLine();
    }
}

从上面的代码可以看出,当使用从datetime到datetimeoffset的隐式转换时,偏移从10月25日的+1小时变为+2小时:早上2点。但是,当使用GetDaylightChanges方法分析当前的daylightaving时,会告知更改应该在10月25日3点发生。

在我脑海中,偏移应该在3点钟变为+2,而不是2点,或者我错了?

PS:此代码在具有瑞典时区设置的瑞典机器上运行。

1 个答案:

答案 0 :(得分:3)

首先,GetDaylightChanges准确无误 - clocks did go back in Sweden at 3am local time

其次,这并不意味着您在BCL的任何地方都显示过错误。问题只是02:00:00发生两次 - 一次在时钟回归之前,一次又一次。换句话说,它发生在2015-10-25 02:00:00 +02:00和2015-10-25 02:00:00 +01:00。您如何期望隐式转换告诉您的意思?两者都是有效的结果,它碰巧选择了后者,尽管很遗憾,这种行为是未指定的,至少在隐式转换文档和DateTimeOffset构造函数文档中都是如此。

这就是为什么在我的Noda Time库中,当您从LocalDateTime映射到ZonedDateTime时(通过应用时区),您必须说出您想要的内容如果值不明确或被跳过,则会发生 - 因此在这种情况下,您可以选择将其解析为2015-10-25 02:00:00的较晚或较早发生。

基本上这是你应该考虑的事情,并决定你希望你的应用程序如何表现......然后你应该使用你正在使用的任何API来指定你想要的行为。某些API比其他API更容易:)