我有调用第三方Java SOAP方法的C#代码。该方法返回一个事件列表。正常情况下,事件的时间戳为毫秒<2014-11-24T06:04:02.699096>。但是,返回到我的C#代码的特定事件类型没有毫秒<2014-11-24T00:00:00>。(始终是从00:00:00开始的一天。)但是,如果我从SOAP进行调用,时间戳确实有毫秒<2014-11-24T00:00:00.000000>。
我遇到的问题是,当我下一次使用收到的时间戳调用Java方法时。如果不包括毫秒,2014-11-24T00:00:00而不是2014-11-24T00:00:00.000000,调用将返回错误。“无法使用样式"xsd.timestamp.micro”将值"2014-11-24T00:00:00“分析为日期”
如何强制C#包含毫秒?
我尝试过使用字符串来回切换:
string timeString = recvdTimestamp.ToString("yyyy-MM-ddThh:mm:ss.ffffff");
newTimestamp = Convert.ToDateTime(timeString);使用构造函数:
newTimestamp = new DateTime(recvdTimestamp.Year,
recvdTimestamp.Month,
recvdTimestamp.Day,
recvdTimestamp.Hour,
recvdTimestamp.Minute,
recvdTimestamp.Second,
0);加减时间
recvdTimestamp = recvdTimestamp.AddTicks(125);
recvdTimestamp = recvdTimestamp.AddTicks(-125);但是,每次我的C#例程都会发送2014-11-24T00:00:00,而从不添加.000000。
发布于 2015-03-19 22:21:14
问题实际上出在Java端。在与微软支持人员一起工作后,我们可以看到DateTime字段中总是有尾随的零。当序列化为字符串时,它总是被丢弃。在研究工作的过程中,我发现这实际上是正确的行为。我在W3C可扩展标记语言标准中找到了以下内容:
来自:http://www.w3.org/TR/xmlschema-2/#dateTime
3.2.7.2规范表示
除了秒表示法、'24:00:00‘时间表示法和时区(对于时区值)中的尾随小数零数字之外,从文字到值的映射是一对一的。当存在多个可能的表示时,规范表示如下所示:
·表示小时的两位数字不能是'24';
·小数第二个字符串,如果存在,不能以“0”结尾;
·对于时区值,必须用'Z‘表示时区(所有时区dateTime值都是UTC值)。
根据标准,以微秒为单位显示尾随零实际上是不允许的。
发布于 2014-11-26 23:43:55
在要序列化/反序列化的类上实现System.Xml.Serialization.IXmlSerializable。将自定义格式添加到read和write方法中。
[Serializable]
[XmlRoot("Vehicle")]
public class Vehicle : System.Xml.Serialization.IXmlSerializable
{
[XmlElement(IsNullable = true)]
public string Wheels { get; set; }
[XmlElement(IsNullable = true)]
public string Windows { get; set; }
[XmlElement]
public int Doors { get; set; }
[XmlElement]
public Engine Engine { get; set; }
[XmlElement]
public DateTime ManufactureTimestamp { get; set; }
#region IXmlSerializable Members
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
reader.MoveToContent();
while (reader.Read())
switch (reader.Name)
{
case "Wheels":
Wheels = reader.ReadString();
break;
case "Windows":
Windows = reader.ReadString();
break;
case "Doors":
int doors = 0;
int.TryParse(reader.ReadString(), out doors);
Doors = doors;
break;
case "Engine":
Engine = (Engine)Enum.Parse(typeof(Engine), reader.ReadString());
break;
case "ManufactureTimestamp":
ManufactureTimestamp = Convert.ToDateTime(reader.ReadString()).ToUniversalTime();
break;
};
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteElementString("Wheels", Wheels);
writer.WriteElementString("Windows", Windows);
writer.WriteElementString("Doors", Doors.ToString());
writer.WriteElementString("Engine", Engine.ToString());
writer.WriteElementString("ManufactureTimestamp", ManufactureTimestamp.ToString("yyyy-MM-ddThh:mm:ss.ffffff"));
}
#endregion
}示例用法:
private Vehicle _vehicle = new Vehicle
{
Doors = 4,
Wheels = "22 inch",
Windows = "Tinted",
Engine = Engine.V6,
ManufactureTimestamp = Convert.ToDateTime("2014-11-24T06:04:02.000000")
};
[TestMethod]
public void SerializeObjectToXmlString()
{
string xml = XmlSerializationHelper.Serialize<Vehicle>(_vehicle);
Assert.IsTrue(xml.Contains("<Wheels>22 inch</Wheels>"));
Assert.IsTrue(xml.Contains("<ManufactureTimestamp>2014-11-24T06:04:02.000000</ManufactureTimestamp>"));
}https://stackoverflow.com/questions/27112287
复制相似问题