当种类为Utc时,从datetime UTC转换为datetimeoffset时出错
当种类为Utc时,将UTC中的DateTime转换为DateTimeOffset 时出错。 origDateTime来自webservice,所以我不能控制内容或格式。 在大多数情况下它与Kind = Unspecified(即使艰难的时间在Utc),然后它的工作,但在极少数情况下Kind = Utc,然后转换为DateTimeOffset引发异常: “UTC抵消Utc DateTime实例必须为0. \ r \ n参数名称:偏移量“ 我应该如何解决它?当种类为Utc时,从datetime UTC转换为datetimeoffset时出错
try {
//cause error !!!!
DateTime databaseUtcTime = DateTime.Parse("4/2/2016 6:25:20 PM");
var localTimeTemp = databaseUtcTime.ToLocalTime();
DateTime origDateTime = localTimeTemp.ToUniversalTime();
//this is working
//DateTime origDateTime = DateTime.Parse("4/2/2016 6:25:20 PM");
string timeZoneName = "Pacific Standard Time";
TimeZoneInfo localTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName);
DateTimeOffset localTime = new DateTimeOffset(origDateTime, localTimeZone.GetUtcOffset(origDateTime));
return localTime;
}
catch (Exception ex) {
string msg = ex.Message;
return null;
}
有几件事情:
如果你真的需要切换
DateTime
的Kind
无需调整其价值,使用DateTime.SpecifyKind
。它比处理蜱更清洁。但是,我不认为你真的需要这样做。请勿使用
ToLocalTime
或ToUniversalTime
。这两种方法都将在转换过程中使用服务器的时区设置。-
我不确定您的真的代码实际上是否解析字符串,因为您表示它来自数据库。如果它来自数据库,则不应涉及任何字符串解析。只要做到以下几点:
DateTime databaseUtcTime = (DateTime) yourDataReader["YourDataField"];
-
一旦你的输入,然后可以转换使用
TimeZoneInfo.ConvertTime
功能。您现有的代码无法正确转换时间,它只是在未正确调整时间值的情况下分配偏移量。由于您希望输出为
datetimeoffset
,所以最简单的方法是首先将输入datetime
转换为datetimeoffset
,偏移量为零(因为它来自UTC)。DateTimeOffset dtoUtc = new DateTimeOffset(databaseUtcTime, TimeSpan.Zero);
然后,它是相当简单的转换:
string timeZoneName = "Pacific Standard Time"; TimeZoneInfo localTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName); DateTimeOffset dtoLocal = TimeZoneInfo.ConvertTime(dtoUtc, localTimeZone);
字符串的使用仅用于测试目的,与ToUniversalTime相同。 这只是模拟来自服务器的数据。 你能解释什么是我在构造函数中添加偏移量之间的差异DateTimeOffset localTime = new DateTimeOffset(origDateTime,localTimeZone.GetUtcOffset(origDateTime)); 和你的代码使用ConvertTime? – user2455595
我看到了区别,你的代码真的把日期和修改为{4/2/2016 11:25:20 AM -07:00}根据定义我只需要做偏移量,否则我会使用你的代码的 。 谢谢。 – user2455595
“DateTimeOffset”中的日期和时间是* local *时间,已经针对该偏移进行了调整。这不仅仅是一个.NET的东西 - 它是由ISO8601公约。时间戳“2016-04-02T18:25:20 + 00:00”相当于“2016-04-02T11:25:20-07:00”。如果您只是在不调整时间值的情况下应用偏移量,则实际上是指完全不同的时间点。 –
所以您的问题将得到解决,如果你一直设置你的DateTimeKind
到Unspecified
,不是吗?
试试这个:
DateTime origDateTime = new DateTime(origDateTimeUnspecifiedKind.Ticks, DateTimeKind.Unspecified);
集成与您的例子:
try
{
//cause error !!!!
DateTime databaseUtcTime = DateTime.Parse("4/2/2016 6:25:20 PM");
var localTimeTemp = databaseUtcTime.ToLocalTime();
DateTime origDateTimeUnspecifiedKind = localTimeTemp.ToUniversalTime();
// FIX: specify the kind
DateTime origDateTime = new DateTime(origDateTimeUnspecifiedKind.Ticks, DateTimeKind.Unspecified);
//this is working
//DateTime origDateTime = DateTime.Parse("4/2/2016 6:25:20 PM");
string timeZoneName = "Pacific Standard Time";
TimeZoneInfo localTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName);
DateTimeOffset localTime = new DateTimeOffset(origDateTime, localTimeZone.GetUtcOffset(origDateTime));
return localTime;
}
catch (Exception ex)
{
string msg = ex.Message;
return null;
}
这解决了这个问题。 谢谢。 – user2455595
DATATIME解析使用时区设置,所以无需转换自动转换为UTC时间。与数据库的连接也自动使用UTC时间,所以你的代码没有多大意义。输入在另一时区收集的数据时或在另一时区显示时间时,仅使用时区偏移。网络库函数将时间存储在计算机中,以UTC的数字表示,并在输入或输出时自动转换UTC。 – jdweng
我需要使用不同的时区(根据另一个字段)将每个日期时间转换为datetimeoffset,以便能够显示在不同的时区中。泽维尔回答解决了这个问题。谢谢。 – user2455595