C#从Java SOAP调用中删除毫秒

时间:2014-11-24 19:06:43

标签: c# datetime soap

我有调用第三方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。

2 个答案:

答案 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>"));
    }