防止对DateTime值进行反序列化时的时区转换

时间:2010-07-06 18:05:39

标签: c# datetime xml-serialization timezone

我有一个使用XmlSerializer序列化/反序列化的类。该类包含DateTime字段。

序列化时,DateTime字段由包含GMT偏移量的字符串表示,例如2010-05-05T09:13:45-05:00。反序列化时,这些时间将转换为执行反序列化的机器的本地时间。

由于不值得解释的原因,我想阻止这种时区转换的发生。序列化发生在野外,其中存在此​​类的多个版本。反序列化发生在我控制的服务器上。因此,似乎在反序列化期间最好处理这个问题。

除了实现IXmlSerializable并手动执行所有反序列化之外,我怎样才能实现这一目标?“

4 个答案:

答案 0 :(得分:29)

我做了什么,是使用DateTime.SpecifyKind方法,如下所示:

DateTime dateTime = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Unspecified);

这解决了我的问题,我希望这能帮到你。

答案 1 :(得分:24)

您可以将其解析为DateTime,而不是解析为DateTimeOffset,并使用DateTimeOffset.DateTime属性忽略时区。像这样:

[XmlIgnore()]
public DateTime Time { get; set; }

[XmlElement(ElementName = "Time")]
public string XmlTime
{
    get { return XmlConvert.ToString(Time, XmlDateTimeSerializationMode.RoundtripKind); }
    set { Time = DateTimeOffset.Parse(value).DateTime; }
}

答案 2 :(得分:2)

你能尝试this post建议的东西,并创建一个新的字符串属性,XmlIgnore是现有的吗?

  

将[XmlIgnore]放在Time属性上。

     

然后添加一个新属性:

[XmlElement(DataType="string",ElementName="Time")]
public String TimeString
{
   get { return this.timeField.ToString("yyyy-MM-dd"); }
   set { this.timeField = DateTime.ParseExact(value, "yyyy-MM-dd", CultureInfo.InvariantCulture); }
}

答案 3 :(得分:2)

我知道这已经过时了,但希望将来可以帮助某人。

以下是我反序列化的XML:

<timePeriod>1982-03-31T00:00:00+11:00</t

反序列化XML后,我最终得到了第30个而不是第31个:

enter image description here

看来生成此XML的第三方(我正在使用)在夏令时将TimeZone更改为+11,并在其不是夏令时(DST)时将其保持为+10。

根据Jon Skeet的说法,UTC不应该考虑夏令时:https://stackoverflow.com/a/5495816/495455

<小时/> 另请注意文档Coding Best Practices Using DateTime in the .NET Framework

<子> XML序列化程序始终假定序列化的DateTime值表示本地计算机时间,因此它将计算机本地时区偏移量应用为编码XML时间的偏移部分。当我们将其反序列化到另一台机器上时,从正在解析的值中减去原始偏移量,并添加当前机器的时区偏移量。

<小时/> 以下代码允许我将日期格式化为31,但对于非Daylioght保存日期(在此Feed中给出),它不会100%工作:

TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time");
DateTime easternTimeNow = TimeZoneInfo.ConvertTimeFromUtc(dataPoint.timePeriod, easternZone);
System.Diagnostics.Debug.WriteLine(easternTimeNow.ToString());

因此,该解决方案是修复XML Feed,因此它不会将UTC与DST交替。

编辑: 数据被搞砸的原因

事实证明它并非第三方供应商使用DST更改UTC。 XML feed由Java Swing框架创建,读取SQL dB。通常我建议保持XML标准表示(xsd:dateTime) - IS0 8601,但在这种情况下使用字符串并在T工作后翻录所有内容。免责声明,我仍在尝试更改Feed,建议您不要在PROD中执行此操作。使用风险自负!!