我有调用第三方Java SOAP方法的C#代码。该方法返回事件列表。通常,该事件具有以毫秒为单位的时间戳< 2014-11-24T06:04:02.699096>。但是,特定事件类型将返回到我的C#代码,而没有毫秒< 2014-11-24T00:00:00>。 (它总是从00:00:00开始。)如果我从SOAP UI进行调用,则时间戳确实具有毫秒< 2014-11-24T00:00:00.000000>。
我遇到的问题是当我接收到带有我收到的时间戳的Java方法的下一次调用时。如果不包括毫秒,2014-11-24T00:00:00而不是2014-11-24T00:00:00.000000,则调用返回错误。 "无法解析值" 2014-11-24T00:00:00"作为使用样式" xsd.timestamp.micro"
的日期如何强制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。
答案 0 :(得分:1)
问题实际上是在Java方面。使用Microsoft支持后,我们可以看到尾随零始终位于DateTime字段中。序列化为字符串时总是丢弃它。在研究工作时,我发现这实际上是正确的行为。我在W3C XML标准中找到了以下内容:
来自:http://www.w3.org/TR/xmlschema-2/#dateTime
3.2.7.2规范表示
除了在秒表示中尾随小数零,< 24:00:00'时间表示和时区(对于时间值),从文字到值的映射是一对一的。如果存在多个可能的表示,则规范表示如下:
•代表小时的2位数字不得为' 24&#39 ;;
•小数第二个字符串(如果存在)不得以' 0';
结尾•对于timezoned值,时区必须用' Z'来表示。 (所有timezoned dateTime值均为UTC。)。
根据标准,实际上不允许以微秒为单位显示尾随零。
答案 1 :(得分:0)
在要序列化/反序列化的类上实现System.Xml.Serialization.IXmlSerializable。将自定义格式添加到读取和写入方法。
[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>"));
}