.net – DateTime和xsd:Date的往返XML序列化?

前端之家收集整理的这篇文章主要介绍了.net – DateTime和xsd:Date的往返XML序列化?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
好的,我在这里缺少什么? MSDN说以下关于DateTimeSerializationMode:

In versions 2.0 and later of the .Net
Framework,with this property set to
RoundtripDateTime objects are examined
to determine whether they are in the
local,UTC or an unspecified time
zone,and are serialized in such a way
that this information is preserved.
This is the default behavior and is
recommended for all new applications
that do not communicate with older
versions of the framework.

然而:

namespace ConsoleApplication1 {
    public class DateSerTest {
        [XmlElement(DataType = "date")]
        public DateTime Date { get; set; }
    }

    class Program {
        static void Main(string[] args) {
            DateSerTest d = new DateSerTest { 
                Date = DateTime.SpecifyKind(new DateTime(2009,8,18),DateTimeKind.Utc),};
            XmlSerializer ser = new XmlSerializer(typeof(DateSerTest));
            using (FileStream fs = new FileStream("out.xml",FileMode.Create)) {
                ser.Serialize(fs,d);
            }

            // out.xml will contain:
            // <Date>2009-08-18</Date>

            using (FileStream fs = new FileStream("out.xml",FileMode.Open)) {
                DateSerTest d1 = (DateSerTest) ser.Deserialize(fs);
                Console.WriteLine(d1.Date); // yields: 8/18/2009 12:00:00 AM
                Console.WriteLine(d1.Date.Kind); // yields: Unspecified
            }

            // in.xml:
            // <DateSerTest>
            //     <Date>2009-08-18Z</Date>
            // </DateSerTest>

            using (FileStream fs = new FileStream("in.xml",FileMode.Open)) {
                DateSerTest d1 = (DateSerTest) ser.Deserialize(fs);
                Console.WriteLine(d1.Date); // yields: 8/17/2009 8:00:00 PM
                Console.WriteLine(d1.Date.Kind); // yields: Local
                using (FileStream fs1 = new FileStream("out2.xml",FileMode.Create)) {
                    ser.Serialize(fs1,d1);

                    // out2.xml will contain:
                    // <Date>2009-08-17</Date>
                }
            }
            Console.ReadKey();
        }
    }
}

因此,对于定义为“date”而不是“dateTime”的XSD元素,日期不会以UTC序列化.这是一个问题,因为如果我反序列化这个XML,那么生成的日期将是“未指定的”类型,并且任何转换为​​UTC(实际上应该是无效的,因为UTC的日期应该在往返期间被保留),将至少改变一天的时间,昨天有50%的机会提供日期,具体取决于您是否在格林威治的东部或西部.

日期不得写为:

<Date>2009-08-18Z</Date>

实际上,如果我反序列化包含上述的文档,我会收到一个已经被转换为本地时间的DateTime(我在纽约,所以这是8月17日20:00),如果我立即将该对象序列化回XML,我得到:

<Date>2009-08-17</Date>

所以,UTC被转换为本地的方式,而当地的一部分在出路的时候,这将使它在未来的路上重新出现.我们对8月18日原始UTC日期规格的了解不全面.

以下是W3C对xsd的说法:date:

[Definition:] The ·value space· of
date consists of top-open intervals of
exactly one day in length on the
timelines of dateTime,beginning on
the beginning moment of each day (in
each timezone),i.e. ’00:00:00′,up to
but not including ’24:00:00′ (which is
identical with ’00:00:00′ of the next
day). For nontimezoned values,the
top-open intervals disjointly cover
the nontimezoned timeline,one per
day. For timezoned values,the
intervals begin at every minute and
therefore overlap.

根本的问题是,如果我做以下:

>构造(或以其他方式接收)UTC DateTime值.
>使用将该字段定义为xsd:date的模式将其序列化为XML
>将XML反序列化为DateTime.
>将DateTime转换为UTC(应该没有影响,因为“往返”应该保留这个).

或以下:

>对包含UTC xsd:date对象的XML文档进行反序列化(例如:2009-08-18Z).
>将其序列化回新的XML文档,而不用触摸它.

这些程序中的任何一个应该让我和我放在一起的日期一样.

解决方法

到目前为止,我可以看到获得往返行为的唯一方法是实现Date属性如下,假设所有xsd:date元素都代表UTC:

[XmlElement(DataType = "date")]
public DateTime Date {
    get { return _dt; }
    set { _dt = value.Kind == DateTimeKind.Unspecified ? 
                    DateTime.SpecifyKind(value,DateTimeKind.Utc) : 
                    value.ToUniversalTime(); }
}
我打开了一个Connect问题,从Microsoft回来,确认了我的恐惧:

We have different behaviors for handling Date,Time and DateTime values. For DateTime values,if XmlDateTimeSerializationMode is not Local the information about the kind (UTC,Local or Unspecified) is preserved. This is also true while deserializing. However,for Date and Time,they are always serialized out with the same format: (yyyy-MM-dd for Date and HH:mm:ss.fffffff.zzzzzz for Time). So the information about kind is lost on serializing and deserializing. We are opening a documentation bug on our side in order to improve the documentation about this.

猜你在找的XML相关文章