调用 ToUniversalTime().AddYears().ToLocalTime() 的闰年错误?

发布于 2024-07-14 13:49:06 字数 1084 浏览 5 评论 0原文

我在 .NET 的 DateTime 处理中遇到了可能是闰年的情况,特别是 ToLocalTime()。 这是一些重现问题的代码(我位于太平洋时区):

DateTime dtStartLocal = DateTime.Parse("2009-02-28T23:00:00.0-08:00");
DateTime dtEndLocal = dtStartLocal.AddYears(3);
DateTime dtStartUtc = dtStartLocal.ToUniversalTime();
DateTime dtEndUtc = dtStartUtc.AddYears(3);
DateTime dtEndLocal2 = dtEndUtc.ToLocalTime();
DateTime dtStartLocal2 = dtStartUtc.ToLocalTime();
Console.WriteLine("START: 1={0}, 2={0}", dtStartLocal, dtStartLocal2);
Console.WriteLine("END  : 1={0}, 2={1}", dtEndLocal, dtEndLocal2);
Console.ReadLine();

输出为:

开始:1=2009/2/28 11:00:00 PM,2=2/28/2009 11:00:00 PM
结束 : 1=2012/2/28 11:00:00 PM, 2=2/29/2012 11:00:00 PM

注意我所做的变量 ToUniversalTime().AddYears(3).ToLocalTime()AddYears(3) 不同,它提前一天。

有人遇到过这种情况吗? 如果这是预期的,有人可以解释其背后的逻辑吗?

注意:是的,最好的方法是完全在 UTC 中工作,而不是在它们之间翻转。 这不是影响我的事情,而是我遇到的一个特殊情况。 本质上,我误解了 AddYears() 的工作原理,现在我可以明白为什么它正在做它正在做的事情(请参阅下面我选择的答案)。

I encountered what may be a leap year in .NET's DateTime handling, specifically ToLocalTime(). Here's some code which reproduces the problem (I'm in the Pacific time zone):

DateTime dtStartLocal = DateTime.Parse("2009-02-28T23:00:00.0-08:00");
DateTime dtEndLocal = dtStartLocal.AddYears(3);
DateTime dtStartUtc = dtStartLocal.ToUniversalTime();
DateTime dtEndUtc = dtStartUtc.AddYears(3);
DateTime dtEndLocal2 = dtEndUtc.ToLocalTime();
DateTime dtStartLocal2 = dtStartUtc.ToLocalTime();
Console.WriteLine("START: 1={0}, 2={0}", dtStartLocal, dtStartLocal2);
Console.WriteLine("END  : 1={0}, 2={1}", dtEndLocal, dtEndLocal2);
Console.ReadLine();

The output is:

START: 1=2/28/2009 11:00:00 PM, 2=2/28/2009 11:00:00 PM
END : 1=2/28/2012 11:00:00 PM, 2=2/29/2012 11:00:00 PM

Notice the variable which I did ToUniversalTime().AddYears(3).ToLocalTime() is different than just AddYears(3), it's one day ahead.

Has anyone encountered this? If this is expected, can someone explain the logic behind it?

NOTE: Yes, the best approach is to work entirely in UTC and not flip flop between them. This isn't something which is effecting me, but a peculiarity I encountered. Essentially I misunderstood how AddYears() worked and now I can see why it's doing what it's doing (see my selected answer below).

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

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

发布评论

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

评论(3

无敌元气妹 2024-07-21 13:49:06

我认为这是正确的。

DateTime dtStartUtc = dtStartLocal.ToUniversalTime();

PST 是 UTC-8。 因此,这会将时间转换为 2009 年 3 月 1 日 07:00:00。

DateTime dtEndUtc = dtStartUtc.AddYears(3);

这比之前的时间增加了三年,即 2012 年 3 月 1 日 07:00:00。

DateTime dtEndLocal2 = dtEndUtc.ToLocalTime();

这会将结束时间转换回 PST,即 2012 年 2 月 29 日 11:00:00。

我想说这只是本地时间和 UTC 时间之间转换的副作用。

I think that this is working correctly.

DateTime dtStartUtc = dtStartLocal.ToUniversalTime();

PST is UTC-8. Therefore, this converts the time to March 1, 2009, 07:00:00.

DateTime dtEndUtc = dtStartUtc.AddYears(3);

This adds three years to the previous time, putting it at March 1, 2012, 07:00:00.

DateTime dtEndLocal2 = dtEndUtc.ToLocalTime();

This converts the end time back to PST, which would be February 29, 2012, 11:00:00.

I'd say this is just a side affect of converting between local and UTC time.

浪菊怪哟 2024-07-21 13:49:06

打印时区/校正系数。 当您执行 .ToUniversialTime() 时,它实际上会从您的原始时间(“-08:00”)添加 8 小时,这会将其置于从 2 月 28 日 23:00 开始的第二天 11:00。 因此,如果加上 3 年,那就是 29 日上午 11:00。 如果你做了2年,那就是3月1日,它与闰年无关。

Print the timezone/correction factor. When you do the .ToUniversialTime() it essentially adds the 8 hours from your original time ("-08:00"), which would put it at 11:00 the next day starting from 23:00 hours February 28th. So when you add 3 years to it, it's the 11:00 AM on the 29th. Had you done 2 years, it would have been March 1st, it has nothing to do with the leap year.

甜柠檬 2024-07-21 13:49:06

据我所知,这种行为并不错误。 当您将当地时间转换为 UTC 时,它会有效地将其推入第二天; 3 月 1 日。 添加三年后,它仍为 3 月 1 日。 将其转换回当地时间,它会回滚到前一天,因为 2012 年是闰年,所以是 2 月 29 日。

This behaviour isn't incorrect, as far as I can tell. When you convert the local time to UTC it effectively pushes it into the next day; March 1st. When you add three years, it stays as March 1st. Convert it back to local time and it rolls back to the previous day, which because 2012 is a leap year, is February 29th.

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