views:

2570

answers:

5

I am trying to serialize a .NET TimeSpan object to XML and it is not working. A quick google has suggested that while TimeSpan is serializable, the XmlCustomFormatter does not provide methods to convert TimeSpan objects to and from XML.

One suggested approach was to ignore the TimeSpan for serialization, and instead serialize the result of TimeSpan.Ticks (and use new TimeSpan(ticks) for deserialization). An example of this follows:

[Serializable]
public class MyClass
{
    // Local Variable
    private TimeSpan m_TimeSinceLastEvent;

    // Public Property - XmlIgnore as it doesn't serialize anyway
    [XmlIgnore]
    public TimeSpan TimeSinceLastEvent
    {
        get { return m_TimeSinceLastEvent; }
        set { m_TimeSinceLastEvent = value; }
    }

    // Pretend property for serialization
    [XmlElement("TimeSinceLastEvent")]
    public long TimeSinceLastEventTicks
    {
        get { return m_TimeSinceLastEvent.Ticks; }
        set { m_TimeSinceLastEvent = new TimeSpan(value); }
    }
}

While this appears to work in my brief testing - is this the best way to achieve this?

Is there a better way to serialize a TimeSpan to and from XML?

+1  A: 

I haven't used it myself, but could this help?

Yossi Dahan
+3  A: 

A more readable option woul be to serialize as a string and use the TimeSpan.Parse method to deserialize it. You could do the same as in your example but using TimeSpan.ToString() in the getter and TimeSpan.Parse(value) in the setter.

Rune Grimstad
+9  A: 

The way you've already posted is probably the cleanest. If you don't like the extra property, you could implement IXmlSerializable, but then you have to do everything, which largely defeats the point. I'd happily use the approach you've posted; it is (for example) efficient (no complex parsing etc), culture independent, unambiguous, and timestamp-type numbers are easily and commonly understood.

As an aside, I often add:

[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]

This just hides it in the UI and in referencing dlls, to avoid confusion.

Marc Gravell
+1 Awesome attribute addition.
Walter
A: 

can't comment or rank up, but the comment SoapDuration

[XmlElement, Type=SoapDuration] public TimeSpan TimeSinceLastEvent

or public SoapDuration TimeSinceLastEventTicks

david valentine
+1  A: 

Another option would be to serialize it using the SoapFormatter class rather than the XmlSerializer class.

The resulting XML file looks a little different...some "SOAP"-prefixed tags, etc...but it can do it.

Here's what SoapFormatter serialized a timespan of 20 hours and 28 minutes serialized to:

< myTimeSpan > P0Y0M0DT20H28M0S < /myTimeSpan >

To use SOAPFormatter class, need to add reference to System.Runtime.Serialization.Formatters.Soap and use the namespace of the same name.

This is how it serializes in .net 4.0
Kirk Broadhurst