2010-07-06 85 views
25

我有一個我使用XmlSerializer序列化/反序列化的類。該課程包含DateTime字段。防止DateTime值的反序列化時區轉換

串行化時,DateTime字段由包含GMT偏移量的字符串表示,例如2010-05-05T09:13:45-05:00。反序列化時,這些時間將轉換爲執行反序列化的機器的本地時間。

由於不值得解釋的原因,我想防止發生此時區轉換。序列化發生在野外,這個類的多個版本存在。反序列化發生在我控制的服務器上。因此,這似乎是在反序列化過程中最好的處理方式。

除了執行IXmlSerializable和「手動執行所有的反序列化」,我怎樣才能做到這一點?

+0

任何人都可以給我一個關於這個問題,反之亦然的鏈接? (將.Net服務器的DateTime傳遞給JavaScript客戶端) – Siddhant 2014-06-11 06:21:28

回答

22

而不是解析爲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; } 
} 
+0

另外,因爲我使用的是實體框架,所以必須將[NotMapped]置於[XmlElement ...]之上,但此解決方案適用於我。謝謝 – 2016-05-05 20:58:36

2

你可以嘗試像this後建議,並作出新的字符串屬性和XmlIgnore現有的一個:

把[XmlIgnore]的時間屬性。

然後添加一個新的屬性:

[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); } 
} 
+0

我需要使用更新後的版本反序列化舊版本的類。這不會破壞兼容性嗎?我可以重命名我的DateTime屬性,並添加一個字符串屬性,它具有與DateTime相同的名稱。但是,這會破壞引用DateTime屬性的客戶端。 – Odrade 2010-07-06 18:43:32

+1

哦,我現在看到元素名稱在Xml中保持不變。讓我試試這個。 – Odrade 2010-07-06 18:46:13

+1

此代碼不適用於您的現有客戶端,因爲DateTime.ParseExact將失敗(因爲時間不是這種格式)。如果您解析爲DateTimeOffset,則它將與您的現有客戶端一起工作。 – 2010-07-06 19:37:29

2

我知道這是舊的,但希望這可以幫助別人的未來。

這裏是我反序列化XML:

enter image description here

看來誰生產的第三方:

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

反序列化XML我結束了30號不是31後這個XML(我正在使用)在夏令時期間將TimeZone更改爲+11,並且在不是夏令時(DST)時將其保持爲+10。

根據喬恩斯基特UTC的不應該考慮DST:https://stackoverflow.com/a/5495816/495455


還要注意文檔 Coding Best Practices Using DateTime in the .NET Framework

XML序列總是假定被序列化DateTime值代表本地計算機的時間,所以它將機器本地時區偏移量用作編碼的XML時間的偏移量部分。當我們將其反序列化到另一臺機器上時,將從正在解析的值中減去原始偏移量,並添加當前機器的時區偏移量。


下面的代碼讓我得到格式化爲31號的日期,但它不會工作100%非Daylioght節約時間(在此飼料給出):

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

因此,解決方案是修復XML提要,以便它不會替代UTC與DST。

編輯:爲什麼數據搞砸了

事實證明它不是第三方供應商更改與DST的UTC。 XML提要由讀取SQL dB的Java Swing框架創建。通常我會建議保持XML標準表示形式(xsd:dateTime) - IS0 8601,但在這種情況下,使用字符串並在T工作後撕掉所有內容。免責聲明,我仍然試圖改變Feed,建議您不要在PROD中這樣做。請自擔風險!

27

我做什麼,這是使用DateTime.SpecifyKind方法,如下:

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

這解決了我的問題,我希望這可以幫助您。