我对XmlConvert
和DateTime
有问题。
当使用XmlConvert.ToDateTime(String)
转换某些字符串时,将结果DateTime
转换回使用XmlConvert.ToString(DateTime)
的字符串,结果字符串与原始字符串不同,具体取决于本地时区。
以下控制台应用程序代码演示了该问题:
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);
}
}
}
}
在我的电脑(Windows 7 x64,时区UTC+02:00,带日光)上运行此程序时,我有以下输出:
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
当转换为不同字符串的结果时,如何可能?
在这种情况下,有没有办法使它输出原始字符串?
谢谢。
最佳答案
首先,XmlConvert.ToDateTime(String)
过载是过时的。文档清楚地指定您应该改用XmlConvert.ToDateTime(String, XmlDateTimeSerializationMode)
。有了它,您可以指定XmlDateTimeSerializationMode
,它记录如下:
xmldatetimeserializationmode值之一,指定如果日期是utc日期,则应将其转换为本地时间还是保留为协调世界时(utc)。
当您有一个DateTime
实例时,它的构造方式(例如,它的时区)将丢失。时区将从原始字符串中正确解析并转换为UTC或本地时间,但转换后的时区将在该过程中丢失。
如果要保留时区偏移量,请使用DateTimeOffset
类。它的行为类似于DateTime
,但保留了从中创建它的时区偏移量。XmlConvert
有一个ToDateTimeOffset
方法,可以完全满足您的需要。下面是一个工作示例:
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);
}
您现在唯一的问题是
+00:00
将被序列化为Z
,如果您自己格式化newString
,这是可以避免的,例如:string newString = String.Format("{0:yyyy-MM-ddTHH:mm:ss.fffffffzzz}", dateTime);