views:

67

answers:

2

I have a class that I serialize/deserialize using XmlSerializer. This class contains a DateTime field.

When serialized, the DateTime field is represented by a string that includes the offset from GMT, e.g 2010-05-05T09:13:45-05:00. When deserialized, these times are converted to the local time of the machine performing the deserialization.

For reasons not worth explaining, I'd like to prevent this timezone conversion from happening. The serialization happens out in the wild, where multiple version of this class exist. The deserialization happens on a server that's under my control. As such, it seems like this would be best handled during deserialization.

How can I make this happen, other than implementing IXmlSerializable and doing all of the deserialization "by hand?"

+2  A: 

Instead of parsing as a DateTime you can parse it as a DateTimeOffset and use the DateTimeOffset.DateTime property to ignore the timezone. Like this:

[XmlIgnore()]
public DateTime Time { get; set; }

[XmlElement(ElementName = "Time")]
public string XmlTime
{
    get { return XmlConvert.ToString(Time, XmlDateTimeSerializationMode.RoundtripKind); }
    set { Time = DateTimeOffset.Parse(value).DateTime; }
}
Adam Hughes
Adam, can you provide an example of this?
John Saunders
This is cleaner than the accepted answer, since I don't have to do any string manipulation to accept inputs from the old class. I'd accept if I could.
Odrade
+1  A: 

Could you try something like this post suggests and make a new string property and XmlIgnore the existing one:

Put [XmlIgnore] on the Time property.

Then add a new property:

[XmlElement(DataType="string",ElementName="Time")]
public String TimeString
{
   get { return this.timeField.ToString("yyyy-MM-dd"); }
   set { this.timeField = DateTime.ParseExact(value, "yyyy-MM-dd", CultureInfo.InvariantCulture); }
}
SwDevMan81
I need to deserialize old versions of the class using the updated version. Won't this break compatability? I can rename my DateTime property and add a string property that has the same name that the DateTime used to. But, this will break clients that reference the DateTime property.
Odrade
Oh, I see now that the Element name will stay the same in the Xml. Let me try this out.
Odrade
This code won't work with your existing clients because the DateTime.ParseExact will fail (since the time isn't in that format). If you parse as a DateTimeOffset instead it will work with your existing clients.
Adam Hughes
I adapted this approach to my situation (remove the UTC offset when it's there, then parse). Your approach does look cleaner, though.
Odrade