转换DateTime.Now至UTC-11时区时抛出异常,如何解决?
问题解决方法
首先明确错误原因:TimeZoneInfo.ConvertTimeToUtc的规则是:
- 当传入的
DateTime对象的Kind为Local时,第二个参数sourceTimeZone必须是TimeZoneInfo.Local(本地时区) - 当
Kind为Utc时,sourceTimeZone必须是TimeZoneInfo.Utc - 只有当
Kind为Unspecified时,才能传入任意时区作为sourceTimeZone
你的代码里,DateTime.Now的Kind默认是Local,但你传入了UTC-11时区作为sourceTimeZone,违反规则导致报错。用SpecifyKind设置为Local只会维持问题现状,因为Kind仍为Local,和sourceTimeZone不匹配。
根据你将DateTime.Now转换为UTC-11时区的需求,提供两种正确实现方式:
方式一:直接将本地时间转换为UTC-11时区时间
使用TimeZoneInfo.ConvertTime方法实现跨时区转换,无需纠结Kind匹配问题:
// 查找UTC-11时区(用TimeSpan判断比字符串更可靠) TimeZoneInfo utcMinus11Zone = TimeZoneInfo.GetSystemTimeZones() .FirstOrDefault(x => x.BaseUtcOffset == TimeSpan.FromHours(-11)); if (utcMinus11Zone != null) { DateTime localTime = DateTime.Now; // 将本地时间转换为UTC-11时区时间 DateTime utcMinus11Time = TimeZoneInfo.ConvertTime(localTime, TimeZoneInfo.Local, utcMinus11Zone); Console.WriteLine($"本地时间:{localTime}"); Console.WriteLine($"UTC-11时区时间:{utcMinus11Time}"); } else { Console.WriteLine("系统中未找到UTC-11时区"); }
方式二:先转UTC再转UTC-11时区(可选)
如果需要先获取UTC时间,再转换为UTC-11时区,可使用以下代码:
TimeZoneInfo utcMinus11Zone = TimeZoneInfo.GetSystemTimeZones() .FirstOrDefault(x => x.BaseUtcOffset == TimeSpan.FromHours(-11)); if (utcMinus11Zone != null) { DateTime utcTime = DateTime.UtcNow; DateTime utcMinus11Time = TimeZoneInfo.ConvertTimeFromUtc(utcTime, utcMinus11Zone); Console.WriteLine($"UTC时间:{utcTime}"); Console.WriteLine($"UTC-11时区时间:{utcMinus11Time}"); } else { Console.WriteLine("系统中未找到UTC-11时区"); }
额外提示
用BaseUtcOffset查找时区可能存在歧义(部分时区会有夏令时调整,基准偏移相同但实际时间会变化)。如果要精准定位某个时区,建议使用TimeZoneInfo.FindSystemTimeZoneById:Windows系统中萨摩亚时区的ID是"Samoa Standard Time",Linux/macOS中是"Pacific/Samoa"。
内容的提问来源于stack exchange,提问作者Gabriel Scarafia
相关产品推荐
相关产品推荐

