C#DateTime无法识别时区更改(BST)

来自阿涅格

几周前,即2016年3月27日,英国的时钟向前移动了一个小时。在01:00,时钟“跳”到02:00

http://www.timeanddate.com/time/dst/events.html

这意味着“ 2016年3月27日,01:30”是无效的日期时间,即,它并不表示实际发生的时间。

当Java日期时间解析器无法理解传递给它的时间时,这最近使我们陷入困境。但是,C#DateTime似乎根本没有任何问题。

DateTime dt = DateTime.Parse("2016-03-27 01:30:00"); 
bool invalid = TimeZoneInfo.Local.IsInvalidTime(dt);

尽管invalid正确设置为trueDateTime但存储它似乎没有任何问题。

此外,以下声明:

diff = new DateTime(2016, 3, 27, 2, 30, 0) - new DateTime(2016, 3, 27, 0, 30, 0);

导致TimeSpan代表2小时,这是不正确的。

为什么DateTime类型不考虑DST?

马特·约翰逊·品特

因此,这里唯一的问题是:

为什么DateTime类型不考虑DST?

简短答案

因为那是DateTime结构的设计方式。

MSDN文档

时区之间的转换操作(例如,UTC与本地时间之间,或一个时区与另一个时区之间)的转换操作考虑了夏令时,但算术和比较操作没有考虑。

更长的答案

.NETDateTime仅跟踪两个逻辑值,TicksKind在内部,出于性能和兼容性的原因,将它们合并为单个64位整数,但是您可以将它们视为两个单独的值。

  • Ticks自纪元值以来跟踪100纳秒间隔的数量0001-01-01 00:00:00

  • Kind跟踪元数据是否Ticks旨在表示UTC时间,计算机本地时区或其他未指定时区中的时间。

与一个工作的每个函数DateTime应该采取Kind考虑。框架中的许多人都这样做。有些没有。许多其他图书馆,甚至有些与时间有关的图书馆,都完全忽略了它。

调用时DateTime.Parse("2016-03-27 01:30:00")Kind设置为Unspecified,因为没有上下文。您提供的值不一定在任何特定时区,因此0001-01-01 00:00:00纪元日期也不是换句话说,您可以将其视为不固定为与UTC或任何DST规则的任何偏移量的日期和时间。

请注意,这与Java和JavaScript截然不同,Java和JavaScript的Date对象跟踪的时间间隔为自1970-01-01 00:00:00 UTC纪元以来的毫秒数始终是UTC,.NET可能存在也可能没有。

有多种方法可以解决此问题。到目前为止,最好的办法是使用更加合理的API,该API由Noda Time开源库提供。但是,如果只想使用.NET内置的功能,则可以考虑使用该DateTimeOffset结构。不同于DateTime,它会跟踪其与UTC的偏移量,并在进行数学运算时将其考虑在内。

您仍然必须使用来检查输入是否无效TimeZoneInfo.IsInvalidTime.NET没有内置的API会在解析时在无效时间内抛出异常你会,但是,发现在转换功能TimeZoneInfo,如ConvertTimeToUtc意志,如果你在一个无效的时间源的时区传递的确抛出异常。

您还应该检查TimeZoneInfo.IsAmbiguousTime,因为在回退过渡期间给定的值出现了两次,例如2016-10-30 01:30在英国,.NET将始终选择标准时间偏移。虽然这乍看起来似乎是正确的,但请考虑到日光实例实际上首先发生-这通常是大多数现实世界场景中所需的行为(无论如何,根据我的经验)。

此外,关于Java代码,如果还没有,则应考虑使用Java 7及更低版本的Joda Timejava.timeJava 8内置的Java。您会发现它们与前面提到的Noda Time非常相似

最后,我将添加自己非常有根据的断言,即DateTime结构的设计在多种方面违反了SRP特别DateTimeKind是一种可憎的-恕我直言。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

英国夏令时-SimpleDateFormat时区无法识别BST

来自分类Dev

C#DateTime解析

来自分类Dev

时间从冬季更改为夏季时的C#DateTime转换

来自分类Dev

如何将带有时区的json / javascript日期解析为C#DateTime?

来自分类Dev

Java中的C#DateTime

来自分类Dev

C#DateTime扩展方法

来自分类Dev

NSDateFormatter无法识别时区

来自分类Dev

从c#datetime到xsd:datetime

来自分类Dev

无法使php DateTime时区转换正常工作。更改时区不会更改时间

来自分类Dev

如何从C#DateTime返回json日期

来自分类Dev

C#DateTime向下到linq的分钟

来自分类Dev

C#DateTime格式名称

来自分类Dev

C#Datetime转换与javascript的相同操作

来自分类Dev

在Ruby中更改DateTime的时区

来自分类Dev

将Json DateTime转换为C#DateTime

来自分类Dev

Excel datetime与C#DateTime的偏移量

来自分类Dev

将LotusNotes datetime转换为C#DateTime格式

来自分类Dev

C#Datetime到ODBC Datetime转换错误

来自分类Dev

无法识别DateTime格式

来自分类Dev

JDBC连接错误:时区无法识别

来自分类Dev

无法更改kubernetes pod的时区

来自分类Dev

Docker无法更改时区

来自分类Dev

如何将C#DateTime转换为AngularJs

来自分类Dev

将ISO 8601解析为C#DateTime

来自分类Dev

将C#DateTime转换为GregorianCalendar日期

来自分类Dev

将Javascript日期解析为C#DateTime

来自分类Dev

SQL / C#DateTime转换为Javascript变量

来自分类Dev

c#DateTime。将时间重置为0

来自分类Dev

Twitter API created_at字段的C#DateTime