防止对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中执行此操作。 使用风险自负!!