get DateTimeOffset from DateTime (utc) and TimeZoneInfo
我需要将DateTime + TimeZoneInfo转换为DateTimeOffset。
我该怎么做呢? 我假设我必须通过TimeSpan,但后来我不确定夏令时是否会得到妥善处理..
谢谢!
UPDATE
1 2 | TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time"); return new DateTimeOffset(DateTime.UtcNow, timeZone.BaseUtcOffset); |
此代码抛出异常..
The UTC Offset for Utc DateTime
instances must be 0.Parameter
name: offset
更新2
对不起,我没有意识到DateTimeOffset只包含偏移量,它不包含实际的区域信息 - 所以我接受@Dave的回答,因为它是我将要使用的..
您应该在DateTime.UtcNow和DateTime.Now之间找到区别
1 2 3 | var now = DateTime.Now; var utcNow = now.ToUniversalTime(); var ts = utcNow - now; |
如果要保存偏移量,通常有利于以UTC格式保存所有日期(特别是在数据库中),因此您不必处理偏移量。您只需在显示之前转换它们,但以UTC进行所有计算。
编辑:如果您有TimeZone对象,则可以将UTC日期转换为该时区的本地时间。
1 | TimeZone.CurrentTimeZone.ToLocalTime() |
要么
1 | DateTime dt = TimeZoneInfo.ConvertTimeFromUtc() |
以下是一些示例代码,它将列出所有时区的日期。
1 2 3 4 5 | var dt = new DateTime(2011, 5, 21, 11, 0, 0); foreach (var tzi in TimeZoneInfo.GetSystemTimeZones()) { Console.WriteLine(string.Format("Time in {0} is {1}", tzi.DisplayName, TimeZoneInfo.ConvertTimeFromUtc(dt, tzi))); } |
这是
1 |
我认为可能有一个更简单的解决方案来消除错误。你试过:
1 2 | TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time"); return new DateTimeOffset(DateTime.UtcNow, timeZone.BaseUtcOffset); |
DateTimeOffset抛出异常。你想要的是这个:
1 2 | TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time"); return new DateTimeOffset(DateTime.UtcNow).ToOffset(timeZone.BaseUtcOffset); |
这不会抛出异常。我不确定为什么接受TimeSpan的构造函数甚至存在,因为它只有在匹配DateTime对象中给出的local或utc偏移时才有效。但它仍然可以减轻头痛。
对于我们这些使用遗留系统的人来说,并不总是可以改变数据的存储方式。如果您只对运行代码的计算机上的特定时区感兴趣,则可以使用以下扩展方法。 DateTime和DateTimeOffset之间存在隐式转换,它考虑了"DateTime.Kind"属性。
1 2 3 4 | public static DateTimeOffset ToDateTimeOffset(this DateTime dt) { return DateTime.SpecifyKind(dt, DateTimeKind.Local); } |