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

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

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

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

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

您可以将其解析为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; } } 

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

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

这解决了我的问题,希望这对你有帮助。

你可以尝试这样的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); } } 

我知道这是旧的,但希望这有助于将来的某个人。

这是我反序列化的XML:

 1982-03-31T00:00:00+11:00 

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

在此处输入图像描述

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

根据Jon Skeet的统计,UTC不应该考虑DST: https : //stackoverflow.com/a/5495816/495455


另请注意.NET Framework中使用DateTime的文档编码最佳实践 :

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交替。

编辑: 为什么数据被搞砸了

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