C# 当反序列化带有数据类型time的XmlElement注释的属性时,XmlSerializer不考虑本地时区
当我使用C# 当反序列化带有数据类型time的XmlElement注释的属性时,XmlSerializer不考虑本地时区,c#,timezone,xmlserializer,C#,Timezone,Xmlserializer,当我使用XmlSerializer.deserialize反序列化时间字符串时,我希望它考虑我的本地时区,以便 00:00:00.0000000+01:00 解析为00:00,因为我位于时区GMT+1 我弄错了吗 下面是我正在运行的测试xml反序列化的代码: using System; using System.IO; using System.Xml.Serialization; using Microsoft.VisualStudio.TestTools.UnitTesting; nam
XmlSerializer.deserialize
反序列化时间字符串时,我希望它考虑我的本地时区,以便
00:00:00.0000000+01:00
解析为00:00,因为我位于时区GMT+1
我弄错了吗
下面是我正在运行的测试xml反序列化的代码:
using System;
using System.IO;
using System.Xml.Serialization;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Testing
{
[TestClass]
public class FooTest
{
[TestMethod]
public void Test()
{
var serializer = new XmlSerializer(typeof(Foo),
new XmlRootAttribute("Foo"));
var xml = "<Foo><TheTime>00:00:00.0000000+01:00</TheTime></Foo>";
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.Write(xml);
writer.Flush();
stream.Position = 0;
var f = (Foo) serializer.Deserialize(stream);
Assert.AreEqual("00:00", f.TheTime.ToShortTimeString()); // actual: 01:00
}
[Serializable]
public class Foo
{
[XmlElement(DataType = "time")]
public DateTime TheTime { get; set; }
}
}
}
使用系统;
使用System.IO;
使用System.Xml.Serialization;
使用Microsoft.VisualStudio.TestTools.UnitTesting;
命名空间测试
{
[测试类]
公务舱
{
[测试方法]
公开无效测试()
{
var serializer=新的XmlSerializer(typeof(Foo),
新的XmlRootAttribute(“Foo”);
var xml=“00:00:00.0000000+01:00”;
var stream=newmemoryStream();
var writer=新的StreamWriter(流);
Write.Write(xml);
writer.Flush();
流位置=0;
var f=(Foo)序列化程序。反序列化(流);
Assert.AreEqual(“00:00”,f.TheTime.toSortTimeString());//实际值:01:00
}
[可序列化]
公开课Foo
{
[xmlement(DataType=“time”)]
公共日期时间时间{get;set;}
}
}
}
不幸的是,当xs:time
值包含偏移量(在XSD规范中是可选的)时,没有内置类型可以将其反序列化为
相反,您需要定义一个自定义类型,并为自定义序列化和反序列化实现适当的接口。下面是一个最小的TimeOffset
结构
[XmlSchemaProvider("GetSchema")]
public struct TimeOffset : IXmlSerializable
{
public DateTime Time { get; set; }
public TimeSpan Offset { get; set; }
public static XmlQualifiedName GetSchema(object xs)
{
return new XmlQualifiedName("time", "http://www.w3.org/2001/XMLSchema");
}
XmlSchema IXmlSerializable.GetSchema()
{
// this method isn't actually used, but is required to be implemented
return null;
}
void IXmlSerializable.ReadXml(XmlReader reader)
{
var s = reader.NodeType == XmlNodeType.Element
? reader.ReadElementContentAsString()
: reader.ReadContentAsString();
if (!DateTimeOffset.TryParseExact(s, "HH:mm:ss.FFFFFFFzzz",
CultureInfo.InvariantCulture, DateTimeStyles.None, out var dto))
{
throw new FormatException("Invalid time format.");
}
this.Time = dto.DateTime;
this.Offset = dto.Offset;
}
void IXmlSerializable.WriteXml(XmlWriter writer)
{
var dto = new DateTimeOffset(this.Time, this.Offset);
writer.WriteString(dto.ToString("HH:mm:ss.FFFFFFFzzz", CultureInfo.InvariantCulture));
}
public string ToShortTimeString()
{
return this.Time.ToString("HH:mm", CultureInfo.InvariantCulture);
}
}
定义此项后,您现在可以将Foo的类型更改为TimeOffset
,您的测试将通过。您还可以删除属性中的DataType=“time”
,因为它是通过GetSchema
方法在对象本身中声明的