Datetime 隐式转换为 Datetimeoffset 会导致不正确的偏移量?
Datetime implicit conversion to Datetimeoffset results in incorrect offset?
在尝试确定给定的日期时间偏移量是发生在时区调整(夏令时)的开始还是结束时,我注意到了一些奇怪的事情。
而且我不确定我是否以错误的方式进行此操作。
以下面的代码为例:
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();
}
}
从上面的代码可以看出,当使用从日期时间到日期时间的隐式转换时,偏移量在 10 月 25:th 凌晨 2 点从 +1 小时变为 +2 小时日期时间偏移量。但是,在使用 GetDaylightChanges 方法分析当前夏令时时,系统告知更改应发生在 10 月 25:th.
的 3 点钟
在我看来,偏移量应该在 3 点钟位置变为 +2,而不是 2 点钟位置,或者我错了吗?
PS:此代码在具有瑞典时区设置的瑞典机器上 运行。
首先,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 中比在其他中更容易 :)
在尝试确定给定的日期时间偏移量是发生在时区调整(夏令时)的开始还是结束时,我注意到了一些奇怪的事情。 而且我不确定我是否以错误的方式进行此操作。
以下面的代码为例:
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();
}
}
从上面的代码可以看出,当使用从日期时间到日期时间的隐式转换时,偏移量在 10 月 25:th 凌晨 2 点从 +1 小时变为 +2 小时日期时间偏移量。但是,在使用 GetDaylightChanges 方法分析当前夏令时时,系统告知更改应发生在 10 月 25:th.
的 3 点钟在我看来,偏移量应该在 3 点钟位置变为 +2,而不是 2 点钟位置,或者我错了吗?
PS:此代码在具有瑞典时区设置的瑞典机器上 运行。
首先,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 中比在其他中更容易 :)