Force Xmlserializer to Serialize Datetime as 'Yyyy-Mm-Dd Hh:Mm:Ss'

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

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); }
}
}

How to serialize Xml Date only from DateTime in C#

You should use the XmlElementAttribute.DataType property and specify date.

public class Birthdays
{
[XmlElement(DataType="date")]
public DateTime DateOfBirth {get;set;}
public string Name {get;set;}
}

Using this outputs

<?xml version="1.0" encoding="utf-16"?>
<Birthdays xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<DateOfBirth>2013-11-14</DateOfBirth>
<Name>John Smith</Name>
</Birthdays>

Another option is to use a string property just for serialization (backed by a DateTime property you use), as at Force XmlSerializer to serialize DateTime as 'YYYY-MM-DD hh:mm:ss' (this is needed for DataContractSerializer, where the xs:date type is not as well-supported)

Date conversion during deserialization

DateTime displays values in local time. It does not support preserving time zone when read from absolute time. So you see ISO-8601 formatted value from -05:00 timezone properly converted to your local timezone.

The only options for serialization back are UTC (Z timezone) and local, see Force XmlSerializer to serialize DateTime as 'YYYY-MM-DD hh:mm:ss' for a way to choose format you want.

If you need to preserve timezone see if some external libraries like NodaTime supports it.

DateTime Format after Serialization with BulkCopy

You are correct that XmlSerializer does not support customized formats for DateTime properties, so you will need a surrogate string property to parse and format your DateTime in the required format.

However, in your XML the Date_Of_Birth is an attribute rather than a child element so you will need to mark the surrogate property with [XmlAttribute(AttributeName="Date_of_Birth")]:

[XmlRoot(ElementName="i")]
public class I
{
[XmlIgnore]
public DateTime SomeDate { get; set; }

[XmlAttribute(AttributeName="Other_Attributes")]
public string Other_Attributes { get; set; }

[XmlAttribute(AttributeName="Date_of_Birth")]
public string Date_of_Birth
{
get { return this.SomeDate.ToString("yyyy-MM-dd HH:mm:ss"); }
set { this.SomeDate = DateTime.Parse(value); }
}

[XmlAttribute(AttributeName="More_Attributes")]
public string More_Attributes { get; set; }
}

[XmlRoot(ElementName="root")]
public class Root {
[XmlElement(ElementName="i")]
public I I { get; set; }
}

Here I used https://xmltocsharp.azurewebsites.net/ to automatically generate classes for your XML then modified the Date_of_Birth property to make use of the underlying DateTime SomeDate property.

Sample fiddle showing that your XML string can be deserialized and re-serialized to:

<root>
<i Other_Attributes="" Date_of_Birth="1999-10-21 00:00:00" More_Attributes="" />
</root>

Serialized XML Date Time value is not correct

.990 is the same as .99, its a fractional number so the last 0 digit is dropped. Digits have importance starting from the left hand side and going to the right. Example:

  • 1.0000 is the same value as 1
  • 2.94 is the same value as 2.940 or 2.9400 or 2.94000.

The serializer just removes the trailing 0 digits. If you want to always capture any trailing 0 digits (not sure why you would) you can add a custom string property and specify the exact output to be serialized and read in there and ignore the DateTime property, see this previous SO post as example.

Serializing DateTime to time without milliseconds and gmt

You could create a string property that does the translation to/from your timeField field and put the serialization attribute on that instead the the real DateTime property that the rest of the application uses.



Related Topics



Leave a reply



Submit