Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force XmlSerializer to serialize DateTime as 'YYYY-MM-DD hh:mm:ss'

I have a XSD schema for some RESTful service. When used in conjunction with xsd.exe tool to generate C# code, XSD's xs:date generates the following code:

[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, DataType="date")]
public System.DateTime time {
    get {
        return this.timeField;
    }
    set {
        this.timeField = value;
    }
}

When deserializing XML to objects using XmlSerializer all seems to be well. The problem I am facing is that the service expects dates to be formatted as YYYY-MM-DD hh:mm:ss and the XSD generated code seems to produce only YYYY-MM-DD.

If I modify XSD manually to xs:dateTime type, the generated C# code produces: 2010-08-20T20:07:03.915039Z.

Basically, how do I force serialization to produce YYYY-MM-DD hh:mm:ss? Is there something to do to XSD or is there something I can do to alter generated C# code?

like image 767
wpfwannabe Avatar asked Aug 20 '10 20:08

wpfwannabe


3 Answers

Use [XmlElement(DataType = "date")] attribute to format your DateTime property value as you need.

From MSDN:

Note:
The attribute that annotates the publicationdate field has a DataType property. There is no type in the .NET Framework that matches the type xs:date completely. The closest match is System.DateTime, which stores date and time data. Specifying the DataType property as a "date" ensures that the XmlSerializer will only serialize the date part of the DateTime object.

like image 22
Bill Gates Avatar answered Nov 10 '22 16:11

Bill Gates


In the past, I've done the following to control datetime serialization:

  • Ignore the DateTime property.
  • Create a dummy string property that serializes/deserializes the way I want

Here is an example:

public class SomeClass
{
    [XmlIgnore]
    public DateTime SomeDate { get; set; }

    [XmlElement("SomeDate")]
    public string SomeDateString
    {
        get { return this.SomeDate.ToString("yyyy-MM-dd HH:mm:ss"); }
        set { this.SomeDate = DateTime.Parse(value); }
    }
}
like image 137
kbrimington Avatar answered Nov 10 '22 16:11

kbrimington


If you only need to clear out the millisecond part. Refer to:

How to truncate milliseconds off of a .NET DateTime

And basicly do something like:

  startDateTimeToUse = startDateTimeToUse.AddTicks(-(startDateTimeToUse.Ticks % TimeSpan.TicksPerSecond));
  endDate = endDate.AddTicks(-(endDate.Ticks % TimeSpan.TicksPerSecond));

I can confirm that this serializes to:

            <startDate>2015-10-31T12:13:04</startDate>
            <endDate>2016-11-10T12:13:06</endDate>

I must also state that Before clearing the milliseconds I'm doing this:

            var startDateTimeToUse = ssStartDateTime.ToUniversalTime();
            var endDate = DateTime.Now.ToUniversalTime();
            startDateTimeToUse = DateTime.SpecifyKind(startDateTimeToUse, DateTimeKind.Unspecified);
            endDate = DateTime.SpecifyKind(endDate, DateTimeKind.Unspecified);

Which I don't know if it's having any effect on the serialization or not at this point

like image 5
João Antunes Avatar answered Nov 10 '22 17:11

João Antunes