我有一个使用XmlSerializer
序列化/反序列化的类。该类包含DateTime
字段。
序列化时,DateTime
字段由包含GMT偏移量的字符串表示,例如2010-05-05T09:13:45-05:00
。反序列化时,这些时间将转换为执行反序列化的机器的本地时间。
由于不值得解释的原因,我想阻止这种时区转换的发生。序列化发生在野外,其中存在此类的多个版本。反序列化发生在我控制的服务器上。因此,似乎在反序列化期间最好处理这个问题。
除了实现IXmlSerializable
并手动执行所有反序列化之外,我怎样才能实现这一目标?“
答案 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个:
看来生成此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中执行此操作。使用风险自负!!