问题
So my client runs some code that writes their current time to an xml file which I then want to read back into a data table but I am getting incorrect time information.
For example their current time is 09:31 their time zone is UTC+1:00.
my code is:
var ds = new DataSet("MyDataSet");
var dt = ds.Tables.Add("MyDataTable");
dt.Columns.Add("MyDateTime", typeof(DateTime));
var startingDateTime = DateTime.Now;
dt.Rows.Add(startingDateTime);
String xmlDT = String.Empty;
using (MemoryStream memoryStream = new MemoryStream())
{
dt.WriteXml(memoryStream,XmlWriteMode.WriteSchema);
xmlDT = Encoding.UTF8.GetString(memoryStream.ToArray());
}
string myFile = @"C:\Users\me\Documents\test1.txt"
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlDT);
doc.Save(myFile);
myFile now contains:
<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:MainDataTable="MyDataTable" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="MyDataTable">
<xs:complexType>
<xs:sequence>
<xs:element name="MyDateTime" type="xs:dateTime" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<MyDataTable>
<MyDateTime>2015-02-12T09:31:37.4250365+01:00</MyDateTime>
</MyDataTable>
</NewDataSet>
This file is then sent to my server in the UK (+00:00) where I then read the file using:
DataTable datatable2 = new DataTable();
datatable2.ReadXml(myFile);
and my datatable now contains 1 row that has a datetime of 08:30 but this is incorrect and I would like it to store the clients time. How would I do this with a change to either my client or server code?
回答1:
so client side you can add the line:
dt.Columns[0].DateTimeMode = DataSetDateTime.Unspecified;
or as a more generic method:
public static void RemoveTimezoneForDataSet(DataSet ds)
{
foreach (DataTable dt in ds.Tables)
{
foreach (DataColumn dc in dt.Columns)
{
if (dc.DataType == typeof(DateTime))
{
dc.DateTimeMode = DataSetDateTime.Unspecified;
}
}
}
}
this saves the XML as:
<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:MainDataTable="MyDataTable" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="MyDataTable">
<xs:complexType>
<xs:sequence>
<xs:element name="MyDateTime" msdata:DateTimeMode="Unspecified" type="xs:dateTime" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<MyDataTable>
<MyDateTime>2015-02-12T09:13:39.8180356</MyDateTime>
</MyDataTable>
</NewDataSet>
So the time gets serialized correctly on the server
回答2:
I suggest simply changing the type of the MyDateTime column to string.
Strings like 2015-02-12T09:31:37.4250365+01:00 can then easily parsed into a DateTimeOffset, which makes handling dates of different timezones easier.
// note I changed +01:00 to +05:00 since I'm in de-DE (+01:00)
// to illustrate the difference
var offset = DateTimeOffset.Parse("2015-02-12T09:31:37.4250365+05:00");
//prints '12.02.2015 09:31:37' (the "original" date)
Console.WriteLine(offset.DateTime);
//prints '12.02.2015 05:31:37 +01:00' (converted to local time)
Console.WriteLine(offset.ToLocalTime());
来源:https://stackoverflow.com/questions/28472824/reading-xml-into-datatable-gives-incorrect-datetime-when-the-time-has-time-zone