打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
c# – IsDayLightSavingTime方法为同一时区和同一时间返回不同的值

下面的代码检查DST中的特定时间或不返回与正常日期时间相同的时间的不同值以及从filetime获取的值:

var tzInfo = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");var reminderstarttime = new DateTime(2018, 3, 10, 22, 0, 0);var referencetime = reminderstarttime.AddHours(10);  // ReferencedTime is in DST;var isRemDstWithNormal = tzInfo.IsDaylightSavingTime(reminderstarttime);var isRefDstWithNormal = tzInfo.IsDaylightSavingTime(referencetime);var reminderStartTimeToUtc = (ulong)reminderstarttime.ToFileTimeUtc();var referenceTimeToUtc = (ulong)referencetime.ToFileTimeUtc();var reminderStartTimeFromUtc = DateTime.FromFileTimeUtc((long)reminderStartTimeToUtc);var referencetimeFromUtc = DateTime.FromFileTimeUtc((long)referenceTimeToUtc);var isRemDSTFromFileTime = tzInfo.IsDaylightSavingTime(reminderStartTimeFromUtc);var isRefTimeDSTFromFileTime = tzInfo.IsDaylightSavingTime(referencetimeFromUtc);Console.WriteLine("isRemDstWithNormal: "   isRemDstWithNormal                    " isRefDstWithNormal: "   isRefDstWithNormal                    " isRemDSTFromFileTime "   isRemDSTFromFileTime                    " isRefTimeDSTFromFileTime: "   isRefTimeDSTFromFileTime);

解决方法:

佐哈尔大概是正确的.关键点是DateTime.ToFileTimeUtc与许多处理DateTime的方法一样,取决于与值关联的Kind.当传递DateTimeKind.Unspecified时,此特定方法假定输入已经是UTC.但是,在您的代码中,您创建的这些值就像它们所给定的时区一样.

让我们归咎于罪魁祸首:

var reminderStartTimeToUtc = (ulong)reminderstarttime.ToFileTimeUtc();var referenceTimeToUtc = (ulong)referencetime.ToFileTimeUtc();

由于reminderstarttime和referencetime都具有Kind == DateTimeKind.Unspecified,因此它们的结果文件时间值不正确.特别:

reminderStartTimeToUtc:  131651928000000000             we wanted:  131652216000000000            difference:       -288000000000  = -8 hours    referenceTimeToUtc:  131652288000000000             we wanted:  131652540000000000            difference:       -252000000000  = -7 hours

如您所见,它们的值与每个相应日期的UTC差异有所不同.

使用DateTime.FromFileTimeUtc在代码中将它们转换回来会返回具有DateTimeKind.Utc的值,这会抛出后续的DST检查:

reminderStartTimeFromUtc:  2018-03-10 22:00:00 UTC  which is equivalent to:  2018-03-10 14:00:00 PST (UTC-8)               we wanted:  2018-03-10 22:00:00 PST (UTC-8)    referencetimeFromUtc:  2018-03-11 08:00:00 UTC  which is equivalent to:  2018-03-11 00:00:00 PST (UTC-8)               we wanted:  2018-03-11 08:00:00 PDT (UTC-8)

请注意,从PST到PDT的切换发生在太平洋标准时间02:00,因此两个值仍处于标准时间.

那么我们如何在没有黑客的情况下得到正确的结果呢?在转换为Windows文件时间之前,只需确保我们的输入值是DateTimeKind.Utc. (DateTimeKind.Local也可以,但是这里不需要涉及本地时区)

// First convert the DateTime values from their unspecified zone-specific times to UTCvar reminderStartTimeUtc = TimeZoneInfo.ConvertTimeToUtc(reminderstarttime, tzInfo);var referenceTimeUtc = TimeZoneInfo.ConvertTimeToUtc(referencetime, tzInfo);// Then convert THOSE values to file-times.var reminderStartTimeToUtc = (ulong)reminderStartTimeUtc.ToFileTimeUtc();var referenceTimeToUtc = (ulong)referenceTimeUtc.ToFileTimeUtc();

其余代码将按原样正确跟随,您将获得预期的结果.

请注意,这些方法的措辞有些令人困惑. DateTime.ToFileTimeUtc表示您正在转换为文件时间,并且具有.Kind == DateTimeKind.Unspecified的输入DateTime将被视为DateTimeKind.Utc.另一种方法DateTime.ToFileTime将Unspecified种类视为Local.但他们都同样对待Utc和Local类型,它们都产生一个Windows文件时间,这本身就是基于UTC的.

作为上述方法的替代方法,您可以使用DateTimeOffset.ToFileTime.在转换为文件时间期间,将正确考虑偏移量.

// construct a DateTimeOffset for each valuevar reminderStartTimeDto = new DateTimeOffset(reminderstarttime, tzInfo.GetUtcOffset(reminderstarttime));var referencetimeDto = new DateTimeOffset(referencetime, tzInfo.GetUtcOffset(referencetime));// then just convert them to file timesvar reminderStartTimeAsFileTime = reminderStartTimeDto.ToFileTime();var referenceTimeAsFileTime = referencetimeDto.ToFileTime();

注意这里没有ToFileTimeUtc,因为DateTimeOffset上没有Kind,所以只有一种方法可以转换它.

最后一件事.请注意,DateTime.AddHours(10)不符合DST差距.因此,当你在谈论上午8点的PDT时,由于春季前进的差距,实际上只有9个小时.实际经过的10小时是太平洋夏令时上午9点.如果在添加10小时之前保留DateTimeOffset类型的值,则可以轻松纠正此问题.

来源:https://www.icode9.com/content-1-287301.html
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Goodspeed's Blog
太赞了!最全的Python 处理日期与时间的全面总结!
python时区设置——pytz模块
【万字长文】详解Python时间处理模块-datetime
谈谈你最熟悉的System.DateTime[下篇]
python不同时区问题
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服