How to serialize a TimeSpan to XML

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?


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.


This is only a slight modification on the approach suggested in the question, but this Microsoft Connect issue recommends using a property for serialization like this:

[XmlIgnore]
public TimeSpan TimeSinceLastEvent
{
    get { return m_TimeSinceLastEvent; }
    set { m_TimeSinceLastEvent = value; }
}

// XmlSerializer does not support TimeSpan, so use this property for 
// serialization instead.
[Browsable(false)]
[XmlElement(DataType="duration", ElementName="TimeSinceLastEvent")]
public string TimeSinceLastEventString
{
    get 
    { 
        return XmlConvert.ToString(TimeSinceLastEvent); 
    }
    set 
    { 
        TimeSinceLastEvent = string.IsNullOrEmpty(value) ?
            TimeSpan.Zero : XmlConvert.ToTimeSpan(value); 
    }
}

This would serialize a TimeSpan of 0:02:45 as:

<TimeSinceLastEvent>PT2M45S</TimeSinceLastEvent>

Alternatively, the DataContractSerializer supports TimeSpan.


Something that can work in some cases is to give your public property a backing field, which is a TimeSpan, but the public property is exposed as a string.

eg:

protected TimeSpan myTimeout;
public string MyTimeout 
{ 
    get { return myTimeout.ToString(); } 
    set { myTimeout = TimeSpan.Parse(value); }
}

This is ok if the property value is used mostly w/in the containing class or inheriting classes and is loaded from xml configuration.

The other proposed solutions are better if you want the public property to be a usable TimeSpan value for other classes.

链接地址: http://www.djcxy.com/p/18498.html

上一篇: Timespan格式

下一篇: 如何将TimeSpan序列化为XML