XmlSerializer
DateTime
Serialization
XML
C#

Force XmlSerializer to serialize DateTime as 'YYYY-MM-DD hhmmss'

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

XmlSerializer does not let you directly customize the text format of a DateTime property while keeping that property as native DateTime in serialized XML. By default, it emits XML Schema date time format, typically with a T separator. If you need a custom format like yyyy-MM-dd HH:mm:ss, the common approach is exposing a string proxy property and ignoring the original DateTime during serialization.

Why Default Formatting Happens

XmlSerializer follows XML Schema conventions for built in types. A DateTime property maps to xs:dateTime, so serialization output is standardized.

If an external system requires non standard text, you need custom mapping logic.

Also note format tokens:

  • yyyy is year of era.
  • MM is month.
  • dd is day.
  • HH is 24 hour clock.
  • mm is minutes.
  • ss is seconds.

Using YYYY can produce surprising week-based year behavior in some contexts.

Proxy String Property Pattern

Use [XmlIgnore] on the real DateTime and expose a string property for XML representation.

csharp
1using System;
2using System.Globalization;
3using System.IO;
4using System.Xml.Serialization;
5
6public class OrderDto
7{
8    [XmlIgnore]
9    public DateTime CreatedAt { get; set; }
10
11    [XmlElement("CreatedAt")]
12    public string CreatedAtText
13    {
14        get => CreatedAt.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
15        set => CreatedAt = DateTime.ParseExact(
16            value,
17            "yyyy-MM-dd HH:mm:ss",
18            CultureInfo.InvariantCulture,
19            DateTimeStyles.None
20        );
21    }
22}
23
24class Program
25{
26    static void Main()
27    {
28        var dto = new OrderDto { CreatedAt = new DateTime(2026, 3, 4, 9, 30, 15) };
29        var serializer = new XmlSerializer(typeof(OrderDto));
30
31        using var sw = new StringWriter();
32        serializer.Serialize(sw, dto);
33        Console.WriteLine(sw.ToString());
34    }
35}

This gives full format control while keeping a typed property in code.

Handling Nullability

For optional values, use nullable DateTime? and an optional string proxy.

csharp
1[XmlIgnore]
2public DateTime? ProcessedAt { get; set; }
3
4[XmlElement("ProcessedAt")]
5public string ProcessedAtText
6{
7    get => ProcessedAt.HasValue
8        ? ProcessedAt.Value.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)
9        : null;
10    set => ProcessedAt = string.IsNullOrWhiteSpace(value)
11        ? null
12        : DateTime.ParseExact(value, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None);
13}

This avoids invalid sentinel dates for missing fields.

IXmlSerializable Option

You can implement IXmlSerializable for full manual control, but it is usually more complex and easier to break. Use it only when proxy property patterns are insufficient.

Manual implementations require careful handling of namespaces, element names, and validation.

Time Zone And Kind Concerns

Custom strings like yyyy-MM-dd HH:mm:ss do not encode offset or timezone. If cross time zone interoperability matters, either:

  • Include offset in format, for example yyyy-MM-dd HH:mm:ss zzz.
  • Agree on UTC storage and document interpretation.

Without explicit zone semantics, data can be misread in distributed systems.

Testing Recommendations

Add serialization and deserialization tests that assert exact output text and round trip behavior.

Key test cases:

  • Normal value.
  • Boundary date values.
  • Invalid incoming date text.
  • Null or empty text for optional fields.

Regression tests protect integration contracts with external XML consumers.

Interoperability Checklist

Before finalizing a custom XML datetime format, confirm exact expectations with the consuming system. Clarify whether timestamps are local, UTC, or business timezone and whether milliseconds are allowed. Ambiguity here causes subtle integration bugs that are hard to diagnose later.

Document format contract in API specs and include sample payloads in integration tests so both sides validate parsing behavior continuously.

Common Pitfalls

  • Trying to force custom text format directly on raw DateTime property with XmlSerializer.
  • Using incorrect date format tokens such as uppercase YYYY.
  • Ignoring timezone semantics in custom date strings.
  • Parsing with current culture instead of invariant culture.
  • Skipping round trip tests for integration critical XML contracts.

Summary

  • XmlSerializer emits standardized date time text for DateTime by default.
  • For custom format, use string proxy properties and ignore native property in XML.
  • Parse and format with invariant culture for stable behavior.
  • Handle nullability explicitly with DateTime? patterns.
  • Add round trip tests to preserve external contract compatibility.

Course illustration
Course illustration

All Rights Reserved.