问题
I having issues with XmlConvert and DateTime.
When converting some string with XmlConvert.ToDateTime(String) then convert resulted DateTime back to string with XmlConvert.ToString(DateTime) and resulting string is different from the original string, and depending on local TimeZone.
The following console application code demonstrating the issue:
using System;
using System.Xml;
namespace DateTimeXmlConvertTest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Original Value\t\t\t\tNew Value");
Console.WriteLine("--------------\t\t\t\t---------");
for (int i = -12; i <= 12; i++)
{
string sign = i < 0 ? "" : "+";
string originalString = "2011-10-01T01:18:54.6652000" + sign + i.ToString("D2") + ":00";
DateTime now = XmlConvert.ToDateTime(originalString);
string newValue = XmlConvert.ToString(now);
Console.WriteLine(originalString + "\t" + newValue);
}
}
}
}
When running this program on my PC (Windows 7 x64, TimeZone UTC+02:00 with Daylight) i have the following output:
Original Value New Value
-------------- ---------
2011-10-01T01:18:54.6652000-12:00 2011-10-01T16:18:54.6652000+03:00
2011-10-01T01:18:54.6652000-11:00 2011-10-01T15:18:54.6652000+03:00
2011-10-01T01:18:54.6652000-10:00 2011-10-01T14:18:54.6652000+03:00
2011-10-01T01:18:54.6652000-09:00 2011-10-01T13:18:54.6652000+03:00
2011-10-01T01:18:54.6652000-08:00 2011-10-01T12:18:54.6652000+03:00
2011-10-01T01:18:54.6652000-07:00 2011-10-01T11:18:54.6652000+03:00
2011-10-01T01:18:54.6652000-06:00 2011-10-01T10:18:54.6652000+03:00
2011-10-01T01:18:54.6652000-05:00 2011-10-01T09:18:54.6652000+03:00
2011-10-01T01:18:54.6652000-04:00 2011-10-01T08:18:54.6652000+03:00
2011-10-01T01:18:54.6652000-03:00 2011-10-01T07:18:54.6652000+03:00
2011-10-01T01:18:54.6652000-02:00 2011-10-01T06:18:54.6652000+03:00
2011-10-01T01:18:54.6652000-01:00 2011-10-01T05:18:54.6652000+03:00
2011-10-01T01:18:54.6652000+00:00 2011-10-01T04:18:54.6652000+03:00
2011-10-01T01:18:54.6652000+01:00 2011-10-01T03:18:54.6652000+03:00
2011-10-01T01:18:54.6652000+02:00 2011-10-01T02:18:54.6652000+03:00
2011-10-01T01:18:54.6652000+03:00 2011-10-01T01:18:54.6652000+03:00
2011-10-01T01:18:54.6652000+04:00 2011-10-01T00:18:54.6652000+03:00
2011-10-01T01:18:54.6652000+05:00 2011-09-30T23:18:54.6652000+03:00
2011-10-01T01:18:54.6652000+06:00 2011-09-30T22:18:54.6652000+03:00
2011-10-01T01:18:54.6652000+07:00 2011-09-30T21:18:54.6652000+03:00
2011-10-01T01:18:54.6652000+08:00 2011-09-30T20:18:54.6652000+03:00
2011-10-01T01:18:54.6652000+09:00 2011-09-30T19:18:54.6652000+03:00
2011-10-01T01:18:54.6652000+10:00 2011-09-30T18:18:54.6652000+03:00
2011-10-01T01:18:54.6652000+11:00 2011-09-30T17:18:54.6652000+03:00
2011-10-01T01:18:54.6652000+12:00 2011-09-30T16:18:54.6652000+03:00
How is it possible when converting to and then from it results with different string?
Is there a way to make it output the original string in this case?
Thanks.
回答1:
First, the XmlConvert.ToDateTime(String) overload is obsolete. The documentation clearly specifies that you should use XmlConvert.ToDateTime(String, XmlDateTimeSerializationMode) instead. With it, you get to specify the XmlDateTimeSerializationMode, which is documented as follows:
One of the XmlDateTimeSerializationMode values that specify whether the date should be converted to local time or preserved as Coordinated Universal Time (UTC), if it is a UTC date.
When you have an instance of DateTime, how it was constructed (its timezone, for instance) will be lost. The timezone will be properly parsed from the original string and converted to either UTC or local time, but what it was converted from is lost in the process.
If you want to preserve the timezone offset, use the DateTimeOffset class. It behaves like DateTime, but preserves the timezone offset from which it was created. XmlConvert has a ToDateTimeOffset method that does exactly what you want. Here's a working example:
Console.WriteLine("{0,33}\t{1,33}", "Original Value", "New Value");
Console.WriteLine("{0}\t{0}", new String('-', 33));
for (int i = -12; i <= 12; i++)
{
string sign = i < 0 ? "" : "+";
string originalString = String.Format(
"2011-10-01T01:18:54.6652123{0}{1:D2}:00", sign, i);
DateTimeOffset dateTime = XmlConvert.ToDateTimeOffset(originalString);
string newString = XmlConvert.ToString(dateTime);
Console.WriteLine("{0}\t{1}", originalString, newString);
}
The only issue you have now is that +00:00 will be serialized to Z, which can be avoided if you format the newString yourself, like so:
string newString = String.Format("{0:yyyy-MM-ddTHH:mm:ss.fffffffzzz}", dateTime);
回答2:
What about XmlConvert.ToDateTime(String, XmlDateTimeSerializationMode), and to preserve the timezone offset use the parametre :
System.Xml.XmlDateTimeSerializationMode.RoundtripKind
来源:https://stackoverflow.com/questions/7787666/xmlconvert-todatetimestring-and-xmlconvert-tostringdatetime-outputs-are