如何用DateTimeOffset在时钟变更日显示23或25小时?(纽约夏令时示例)
问题分析与解决方案
问题原因
你直接使用TimeZoneInfo.BaseUtcOffset创建DateTimeOffset,这个属性返回的是时区标准时间的UTC偏移量,不会随夏令时切换而调整。2024年3月10日纽约切换夏令时,当天本地时间从凌晨2点直接跳到3点,实际时长为23小时,但你用固定的标准偏移计算时,相当于把两天的时间都按标准偏移处理,所以得到了24小时的错误结果。
正确实现方式
应该使用TimeZoneInfo.ConvertTime方法,将未指定时区的DateTime转换为对应时区的DateTimeOffset,该方法会自动识别夏令时并应用正确的UTC偏移量。
F# 代码示例
open System let nyTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time") // 创建未指定时区的本地日期时间 let startLocal = DateTime(2024, 3, 10, 0, 0, 0, DateTimeKind.Unspecified) let stopLocal = DateTime(2024, 3, 11, 0, 0, 0, DateTimeKind.Unspecified) // 转换为对应时区的DateTimeOffset,自动处理夏令时 let start = TimeZoneInfo.ConvertTime(startLocal, nyTimeZone) let stop = TimeZoneInfo.ConvertTime(stopLocal, nyTimeZone) // 计算时长 (stop - start).TotalHours // 输出:23.0
C# 代码示例
using System; var nyTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); DateTime startLocal = new DateTime(2024, 3, 10, 0, 0, 0, DateTimeKind.Unspecified); DateTime stopLocal = new DateTime(2024, 3, 11, 0, 0, 0, DateTimeKind.Unspecified); DateTimeOffset start = TimeZoneInfo.ConvertTime(startLocal, nyTimeZone); DateTimeOffset stop = TimeZoneInfo.ConvertTime(stopLocal, nyTimeZone); double totalHours = (stop - start).TotalHours; // 结果:23.0
补充说明
TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")确实对应IANA时区的America/New_York,你的这个认知是正确的。- 当处理涉及夏令时切换的日期时间计算时,务必使用时区转换方法,避免直接使用固定偏移量,否则会忽略夏令时带来的时间变化。
内容的提问来源于stack exchange,提问作者capitalistcuttle
相关产品推荐
相关产品推荐

