DataSet.ReadXml自动转换UTC时间为本地时间,如何禁用该行为?
问题:DataSet.ReadXml自动转换UTC时间为本地时区,如何禁用?
执行REST API调用SQL语句:
SELECT GETUTCDATE() AS [NOW]
得到的数据集被序列化为如下XML:
<?xml version="1.0" encoding="utf-16"?> <NewDataSet> <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="Table1"> <xs:complexType> <xs:sequence> <xs:element name="NOW" msdata:ReadOnly="true" type="xs:dateTime" /> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> </xs:schema> <Table1> <NOW>2026-04-01T16:15:58.573+00:00</NOW> </Table1> </NewDataSet>
执行反序列化代码(XML字符串存储在变量moData中):
moDataSet = new System.Data.DataSet(); System.IO.StringReader oSR = null; try { oSR = new System.IO.StringReader(s:(string)moData); moDataSet.ReadXml(reader:oSR); } catch { // 异常处理 }
查看数据集中的NOW列时,时间值变为约18:16(当前处于荷兰夏令时,时区为UTC+2),可见DataSet.ReadXml自动将UTC时间转换为了本地时间。请问是否有办法禁用该转换行为?
解决方案
方案1:修改XML Schema的msdata:UseCurrentLocale属性
原XML Schema中msdata:UseCurrentLocale="true"会让DataSet读取时使用当前区域设置自动转换时间,将该属性改为false后,DateTime值会保留原始UTC信息,不会转换为本地时间。
修改后的Schema片段:
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="false">
方案2:读取后手动转换回UTC时间
如果无法修改源XML内容,可在读取完成后遍历数据集,将DateTime值转换为UTC时间:
foreach (DataRow row in moDataSet.Tables["Table1"].Rows) { if (row["NOW"] is DateTime dt) { row["NOW"] = dt.ToUniversalTime(); } }
方案3:使用配置DateTimeHandling的XmlReader读取
手动创建XmlReader并设置DateTimeHandling = XmlDateTimeHandling.RoundtripKind,这样读取时会保留DateTime的Kind属性,避免自动转换:
using (var stringReader = new StringReader((string)moData)) using (var xmlReader = XmlReader.Create(stringReader, new XmlReaderSettings { DateTimeHandling = XmlDateTimeHandling.RoundtripKind })) { moDataSet.ReadXml(xmlReader); }
内容的提问来源于stack exchange,提问作者DinahMoeHumm
相关产品推荐
相关产品推荐

