VB.NET中DateTime对象偏移转换与时区相关问题咨询
解决方案
一、解决转换报错与跨时段构造问题
报错根源是dtNow.AddMinutes(181)生成的DateTime对象,Kind属性是Local(因为dtNow来自DateTime.Now),但你传入的源时区是美国东部时区,两者不匹配导致转换失败。
正确思路是明确绑定时间的时区归属,不要依赖DateTime的Kind属性,改用TimeZoneInfo或DateTimeOffset来处理:
调试场景模拟美国东部时间16:01:
不用本地时间加减分钟,直接构造美国东部时区的目标时间,再转UTC和本地时间:If Debugger.IsAttached Then Dim easternZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time") ' 构造美国东部当天16:01的时间 Dim easternTargetTime As New DateTime(dtNow.Year, dtNow.Month, dtNow.Day, 16, 1, 0) ' 转换为带时区偏移的DateTimeOffset,避免Kind冲突 Dim easternOffset As New DateTimeOffset(easternTargetTime, easternZone.GetUtcOffset(easternTargetTime)) ' 转UTC再转本地时间 Dim utcTime As DateTime = easternOffset.UtcDateTime NYSEclose_localTime = TimeZoneInfo.ConvertTimeFromUtc(utcTime, TimeZoneInfo.Local) Else ' 保留原正常逻辑 NYSEclose = New DateTime(dtNow.Year, dtNow.Month, dtNow.Day, 16, 0, 0) Dim easternZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time") Dim utcTime As DateTime = TimeZoneInfo.ConvertTimeToUtc(NYSEclose, easternZone) NYSEclose_localTime = TimeZoneInfo.ConvertTimeFromUtc(utcTime, TimeZoneInfo.Local) End If通用构造美国东部时间的正确方式(规避跨时段问题):
别用本地时间加减小时的方式(比如dtNow.hour+3),因为时区差会随夏令时变化,跨天/月/年时还会出错。直接构造目标时区的时间,再处理可能的无效时间:Dim easternZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time") ' 构造美国东部当天16:00的时间 Dim easternCloseTime As New DateTime(dtNow.Year, dtNow.Month, dtNow.Day, 16, 0, 0) ' 处理夏令时回拨导致的无效时间(比如11月的凌晨2点重复出现) If TimeZoneInfo.IsInvalidTime(easternCloseTime) Then easternCloseTime = easternCloseTime.AddHours(1) End If ' 转UTC再转本地时间 Dim utcTime As DateTime = TimeZoneInfo.ConvertTimeToUtc(easternCloseTime, easternZone) NYSEclose_localTime = TimeZoneInfo.ConvertTimeFromUtc(utcTime, TimeZoneInfo.Local)
二、"Eastern Standard Time"时区的夏令时有效性
完全不会失效。TimeZoneInfo.FindSystemTimeZoneById里的ID是系统内部唯一标识,"Eastern Standard Time"对应的是完整的美国东部时区(包含夏令时切换规则),并非仅指标准时间。系统会自动根据当前日期判断是使用标准时间(EST)还是夏令时(EDT),时区列表显示的只是标准时区名称,但实际时区对象包含完整的夏令时配置。
你可以用这段代码验证:
Dim easternZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time") Console.WriteLine(easternZone.SupportsDaylightSavingTime) ' 输出True,说明支持夏令时 Console.WriteLine(easternZone.DaylightName) ' 输出"Eastern Daylight Time",显示夏令时名称
内容的提问来源于stack exchange,提问作者Ernesto
相关产品推荐
相关产品推荐

