从DateTime(utc)和TimeZoneInfo获取DateTimeOffset

时间:2011-06-08 19:29:34

标签: c# datetime

我需要将DateTime + TimeZoneInfo转换为DateTimeOffset。

我该怎么做?我假设我必须通过TimeSpan,但后来我不确定夏令时是否会得到妥善处理..

谢谢!

更新

TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time");
return new DateTimeOffset(DateTime.UtcNow, timeZone.BaseUtcOffset);

此代码抛出异常..

  

Utc DateTime的UTC偏移量   实例必须为0. \ r \ nParameter   name:offset

更新2

抱歉,我没有意识到DateTimeOffset只包含偏移量,它不包含实际的区域信息 - 所以我接受@Dave的答案,因为它是我将要使用的..

4 个答案:

答案 0 :(得分:18)

你应该要在DateTime.UtcNow和DateTime.Now之间找到区别

var now = DateTime.Now;
var utcNow = now.ToUniversalTime();
var ts = utcNow - now;

如果要保存偏移量,通常以UTC格式保存所有日期(特别是在数据库中)是有益的,这样您就不必处理偏移量。您只需在显示之前转换它们,但以UTC格式进行所有计算。

编辑:如果您有TimeZone对象,则可以将UTC日期转换为该时区的本地时间。

TimeZone.CurrentTimeZone.ToLocalTime()

OR

DateTime dt = TimeZoneInfo.ConvertTimeFromUtc()

以下是一些示例代码,它将列出所有时区的日期。

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 :(得分:6)

TimeZoneInfoBaseUtcOffset属性,表示偏移量为TimeSpan

这是DateTimeOffset构造函数所期望的偏移量:

var myDTOffset = new DateTimeOffset(myDatetime, mytzInfo.BaseUtcOffset);

答案 2 :(得分:3)

我认为可能有一个更简单的解决方案来消除错误。你试过了:

TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time");
return new DateTimeOffset(DateTime.UtcNow, timeZone.BaseUtcOffset);

DateTimeOffset抛出异常。你想要的是:

TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time");
return new DateTimeOffset(DateTime.UtcNow).ToOffset(timeZone.BaseUtcOffset);

这不会抛出异常。我不确定为什么接受TimeSpan的构造函数甚至存在,因为它只有在匹配DateTime对象中给出的local或utc偏移时才有效。但它仍然可以减轻头痛。

答案 3 :(得分:2)

对于我们这些使用遗留系统的人来说,并不总是可以改变数据的存储方式。如果您只对运行代码的计算机上的特定时区感兴趣,则可以使用以下扩展方法。 DateTime和DateTimeOffset之间存在隐式转换,它考虑了“DateTime.Kind”属性。

public static DateTimeOffset ToDateTimeOffset(this DateTime dt)
{
    return DateTime.SpecifyKind(dt, DateTimeKind.Local);
}