日期时间差运算符考虑夏令时?

发布于 2024-07-17 18:19:39 字数 245 浏览 6 评论 0原文

据我所知 DateTime 类型的差分运算符考虑闰年:那么

new DateTime(2008, 3, 1) - new DateTime(2008, 2, 1) // should return 29 days
new DateTime(2009, 3, 1) - new DateTime(2009, 2, 1) // should return 28 days

但是夏令时呢?

As far as I know the difference operator of the DateTime type considers leap years: so

new DateTime(2008, 3, 1) - new DateTime(2008, 2, 1) // should return 29 days
new DateTime(2009, 3, 1) - new DateTime(2009, 2, 1) // should return 28 days

But what about daylight saving?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

美男兮 2024-07-24 18:19:40

.NET 无法正确处理夏令时,尽管它给出了您想要的答案。 您想要不正确的答案。

简短版本:

  • .NET 如何知道 1977 年由于能源危机,夏令时全年有效?

  • 当以色列议会每年决定夏令时规则时,.NET 如何知道以色列的夏令时规则?

  • .NET 如何知道美国在二战期间全年实行 DST,并且从 1945 年到 1966 年 DST 规则因地区而异,并且这些规则仍然因地区而异。

    .NET 是如何知道的

.NET 尝试逃避,并使用当前的夏令时规则,即使它们没有或将要生效。 结果是你得到的答案虽然是你认为你想要的,但却是不正确的。

来自 Raymond Chen 的博客文章,为什么夏令时不直观

为什么 (win32) 时区转换函数不使用适合一年中某个时间的时区?

...

Win32 不会尝试猜测哪个
时区规则当时生效
其他时间。 所以 Win32 会说:“星期四,
2002 年 10 月 17 日上午 8:45:38(太平洋标准时间)”。

注意:太平洋标准时间。 甚至
尽管 10 月 17 日是在太平洋期间
夏令时时间,Win32显示时间
作为标准时间,因为那就是
现在是现在

.NET 说,“好吧,如果规则
现在的效果也生效了
2003 年 10 月 17 日,那么就是
夏令时
”因此显示
“2003 年 10 月 17 日,星期四,上午 9:45
PDT”- 夏令时。

所以你得到的答案是错误的。但既然你期望得到错误的答案,这就是你得到的答案。

.NET does not handle daylight savings time correctly, even though it gives answers you want. You want incorrect answers.

Short version:

  • How can .NET know that in 1977 daylight savings time was in effect the entire year, due to the energy crisis?

  • How can .NET know what the daylight savings rules will be in Israel, when the rules are decided year-to-year by the Knesset?

  • How is .NET to know that the US ran on DST year round during WWII, and from 1945 to 1966 the DST rules varied region to region, and the rules still do vary region to region.

.NET tries a cop-out, and uses the current daylight savings rules, even if they weren't, or will be, in effect. The result is that you get answers which, while are what you think you want, are incorrect.

From Raymond Chen's blog entry, Why Daylight Savings Time is nonintuitive:

Why don't the (win32) time zone conversion functions use the time zone appropriate for the time of year?

...

Win32 does not attempt to guess which
time zone rules were in effect at that
other time. So Win32 says, "Thursday,
October 17, 2002 8:45:38 AM PST
".

Note: Pacific Standard Time. Even
though October 17 was during Pacific
Daylight Time, Win32 displays the time
as standard time because that's what
time it is now.

.NET says, "Well, if the rules in
effect now were also in effect on
October 17, 2003, then that would be
daylight time
" so it displays
"Thursday, October 17, 2003, 9:45 AM
PDT" - daylight time.

So the answers you get are wrong. But since you expect the wrong answer, it's what you get.

灯角 2024-07-24 18:19:40

我认为不会。 文档只是说存储了 DateTime作为自 0001 年 1 月 1 日午夜 12:00:00 以来的刻度数,但它没有说明午夜实际上在哪个时区 - 我不得不假设如果它总是在内部存储在 UTC 中,他们会说所以。

不过,您可以轻松解决此问题:只需执行:

var difference = Dt1.ToUniversalTime() - Dt2. ToUniversalTime()

并且转换为 UTC 将考虑夏令时

I don't think it will. The documentation simply says that a DateTime is stored as the number of ticks since 12:00:00 midnight, January 1, 0001, but it doesn't say in which TimeZone the midnight actually is - I would have to assume that if it was always stored internally in UTC, they would say so.

You can easily get around this though: Just do:

var difference = Dt1.ToUniversalTime() - Dt2. ToUniversalTime()

and the conversions to UTC will take into account daylight savings

倦话 2024-07-24 18:19:40

夏令时比一般的 12 个时区以及使用这些时区的国家更为具体。

不同的国家或国家组使用不同的夏令时日期。

确实有点痛苦,更不用说那些不这样做的国家,或者部分国家。

例如,昆士兰州,澳大利亚没有夏令时,尽管该国其他地区有夏令时。

如果没有,我不会感到惊讶,如果有的话,至少在没有cultureinfo 9的情况下将无法做到这一点)。

Daylight saving time is more specific than the general 12 timezones and which countries used them.

Different countries or groups of countries use different dates for when DST happens.

its a bit of a pain really not to mention the countries which dont do it, or parts of countries.

For example Queensland, AU doenst have DST inspite the rest of the country does.

I would not be surprised if it does not, in the event that it does it would be unable to do it with out a cultureinfo 9at the least).

红墙和绿瓦 2024-07-24 18:19:40

它不会,事实上也不能,因为它既不强迫您使用 UTC 来构造 DateTime,也不允许您在构造时指定 DST 是否有效具有本地时间值的 DateTime。 此外,它允许模式(LT 或 UTC)“未指定”,这只是愚蠢的。

通过允许从本地时间值构造日期时间值,可以构造一个不明确的日期时间值(指定为本地时间)(例如,美国 11 月 2 日凌晨 1 点到凌晨 2 点之间的任何时间,此时本地时间会重复) ) 并且无法确定地转换回 UTC,除非构造函数提供了一个参数来指定 DST 是否对给定本地时间有效

由于它没有提供这样的参数,因此 DateTime 类的设计是不完整且有缺陷的,未能考虑正确指定本地时间所需的所有参数。

我认为这就是他们创建 DateTimeOffset 类的原因,这...如果您感到困惑为什么存在这样一个看似多余的类...那就是原因。

因此,您永远不应该对任何未设置为 DateTimeMode.Utc 的 DateTime 实例进行任何类型的计算。 仅使用 UTC。 实际上,您无法与 LT 进行转换,也无法从 LT 进行转换,因为它被两种不同的错误所破坏。
1. 从 LT 到 UTC 的转换失败了,因为如前所述,它不允许您指定 DST 在 LT 中的那个不明确的小时内是否有效。 哦,它还允许您指定基本上不可能的本地时间,例如当时钟提前设置时我们跳过的时间。
2. 当将过去的 UTC 值转换为本地时间时,Windows 根据 DST 现在是否有效而不是给定时间来偏移 DST,从而搞砸了这一点,这是非常愚蠢的。 当然,当您在文件名中写下、存储或使用的修改时间有一天在 Windows 资源管理器中显示为 HOUR OFF 时,您可能已经注意到了这个问题。 不,你没疯,Windows 只是有一个严重的错误,在 DOS 发布和最新的 .NET 框架之间(大约 2 年来),他们从未找到时间来修复该错误! 当然,该错误会影响 CVS 系统和任何跟踪修改时间的系统。 FAT 文件系统将时间存储为本地时间,这意味着它完全被搞砸了。

It won't and it in fact CANNOT, based on the fact that it does not either force you to use UTC to construct a DateTime nor does it allow you to specify whether DST was in effect when you construct a DateTime with a local time value. Furthermore, it allows the mode (LT or UTC) to be "unspecified", which is just asinine.

By allowing the construction of DateTime values from Local Time values, it's possible to construct a DateTime value (specified as Local Time) which is ambiguous (for example any time between 1 and 2am on November 2nd in the U.S., when the local hour repeats itself) and cannot be deterministically converted back to UTC, UNLESS the constructor provided a parameter for specifying whether DST was in affect for the given local time.

Since it provides no such parameter, the design of the DateTime class is incomplete and flawed, having failed to consider all the parameters necessary to properly specify a local time correctly.

I think that's why they created the DateTimeOffset class, which... if you were confused why such a seemingly redundant class exists... that's why.

As a result, you should never do any kind of calculation with any DateTime instance that is not set to DateTimeMode.Utc. Only use UTC. You actually can't convert either to or from LT, because it's BUSTED by two different bugs, both ways.
1. Going from LT to UTC is busted because, as mentioned, it doesn't allow you to specify whether DST was in effect for that one ambiguous hour in LT. Oh, it also allows you to specify a local hour that's basically impossible, such as the hour we skip over when the clocks are set ahead.
2. When converting a UTC value in the past to a local time, Windows screws that up by offsetting for DST based on whether it's in effect NOW, rather that the given time, which is seriously asinine. Of course, you may have noticed this problem when a modification time you wrote down, stored, or used in the name of a file, one day shows up an HOUR OFF in Windows explorer. No, you're not crazy, Windows just has a serious bug in it, which they never found the time to fix somewhere between the release of DOS and the latest .NET framework (~2 decades)! Of course, that bug affects CVS systems and anything that tracks modification times. The FAT file system stores times as local times, which means that it's just completely screwed.

蓦然回首 2024-07-24 18:19:40

测试一下看看!

编写测试就像为 DST 情况和闰年情况编写测试一样容易。

Test it and see!

Its just as easy to write a test as you have done for the DST case as it is for the leap year case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文