8

I need to know the optimal way of writing/reading DateTime into/from XML. Should I directly write DateTime into XML or DateTime.ToString() into XML?

Second question is how to read the date element from XML. Can casting be used for this? Eg:

(DateTime)rec.Element("Date").value

Or, do I need to parse the string like this? Eg:

DateTime.Parse(rec.Element("Date").value)

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
Pankaj Upadhyay
  • 12,966
  • 24
  • 73
  • 104

3 Answers3

19

You can use casting of an XElement or XAttribute with LINQ to XML, yes... but not of the string itself. LINQ to XML uses the standard XML format, independent of your culture settings.

Sample:

using System;
using System.Xml.Linq;

class Test
{    
    static void Main()
    {
        DateTime now = DateTime.Now;
        XElement element = new XElement("Now", now);

        Console.WriteLine(element);
        DateTime parsed = (DateTime) element;
        Console.WriteLine(parsed);
    }
}

Output for me:

<Now>2011-01-21T06:24:12.7032222+00:00</Now>
21/01/2011 06:24:12
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Casting of XElement is better or parsing the XElement.value ?? – Pankaj Upadhyay Jan 21 '11 at 06:42
  • @Pankaj: I would *definitely* use the LINQ to XML conversions. That way it will use the standard format for storing dates/times in XML, so you can interoperate cleanly with other code (possibly written in other languages). – Jon Skeet Jan 21 '11 at 07:07
  • What do you mean by Linq to XML conversion ? sorry if i am being stupid.. :P ... You mean to say i should write the date directly into XML and then Cast the XElement ....is that what you mean ?? – Pankaj Upadhyay Jan 21 '11 at 07:21
  • 1
    @Pankaj: I mean the conversions performed by the LINQ to XML library, as shown in my answer. – Jon Skeet Jan 21 '11 at 07:25
  • @Jon: Ok...Well as you can see in your example. The format changes as soon as you cast the XML Element. Therefore when the XElement is updated with this value, it will contain the new format. So i think why don't we change the format in the very first place by writing XElement("Now", now.ToString()). What do you say about it?? – Pankaj Upadhyay Jan 21 '11 at 07:35
  • 5
    @Pankaj: The *format* isn't part of the value to start with. You should definitely **not** just call `ToString` on the DateTime. That will get you XML which depends on the culture of the computer you're running it on. What does "03/05/2011" mean - May 3rd or March 5th? It's ambiguous unless you have the format information as well (which *isn't part of the value*). The XML format is standardized, and doesn't suffer from this issue. – Jon Skeet Jan 21 '11 at 07:38
  • @Jon: Hmm...dats a very valid and important point you made. I wasn't thinking it this way...thanks for clearing the air. Please tell me the correct way to update the existing Date Element. Right now, i am updating the field like this **r.Element("Date").value = Date.ToString()** . – Pankaj Upadhyay Jan 21 '11 at 07:47
  • 1
    @Pankaj: Then I suggest you stop doing that :) If you *have* to update an existing element, you could use `r.Element("Date").Value = XmlConvert.ToString(Date, XmlDateTimeSerializationMode.RoundtripKind);` – Jon Skeet Jan 21 '11 at 07:52
  • @Jon: Thanks Buddy...Sorry to take so much of ur time. Now i will read the Date like this **DateTime Date = (DateTime)record.Element("Date")** and update it like this **r.Element("Date").Value = XmlConvert.ToString(Date, XmlDateTimeSerializationMode.RoundtripKind);** – Pankaj Upadhyay Jan 21 '11 at 08:04
  • When i use DateTime? (nullable DateTime), this code **XmlConvert.ToString(Date, XmlDateTimeSerializationMode.RoundtripKind)** giving error – Pankaj Upadhyay Jan 21 '11 at 10:01
  • 1
    @Pankaj: Then you'd need to specify `Date.Value` - that's just a normal part of using nullable value types. Note that if you use the XElement constructor instead, that would just happen by magic :) – Jon Skeet Jan 21 '11 at 10:20
  • @Jon: When i try update using "Date.Value", i get the InvalidOperationException {"Nullable object must have a value."}. Here is the line of code generating error : XmlConvert.ToString(DespatchDate.Value, XmlDateTimeSerializationMode.RoundtripKind); – Pankaj Upadhyay Jan 21 '11 at 10:54
  • 1
    @Pankaj: I'd assumed you'd already tested that the date wasn't null before using that... at this point we've really moved beyond LINQ to XML, into general discussion of nullable value types. I suggest you read up on the details of those - it'll help you for this and other situations. – Jon Skeet Jan 21 '11 at 11:02
  • @Jon: Sorry, in hurrying up i forget to check for null condition. Yes the date is null that's why it's giving error – Pankaj Upadhyay Jan 21 '11 at 11:17
  • @Jon: Here is what i am doing now `PaymentDate.HasValue? XmlConvert.ToString(PaymentDate.Value, XmlDateTimeSerializationMode.RoundtripKind) : ""` Correct me if you feel the code isn't good – Pankaj Upadhyay Jan 21 '11 at 12:08
  • How is the `DateTime parsed = (DateTime) element;` able to cast a XElement to a DateTime? I would have thought that would cause a runtime error. – Justin Apr 17 '12 at 16:33
  • 2
    @Justin: Look at the `XElement` documentation - it provides a custom explicit conversion. If it didn't, it would fail at compile-time. – Jon Skeet Apr 17 '12 at 16:36
  • Oh I see, I didn't know it had that functionality. Thanks. – Justin Apr 18 '12 at 12:17
7

An alternative to @Jon Skeet's answer is to convert the DateTime to a string using the "round trip" format. This converts it to a format that will save and load without losing any information.

string dataToSave = myDateTime.ToString("o");

And convert back again using DateTime.Parse(). The page I've linked to has examples showing you how to convert to/from the string format. All you need to do is store this string into your XML. THis gives you more control over how the data is stored (if you want more control, that is).

Jason Williams
  • 56,972
  • 11
  • 108
  • 137
  • More control, but less portability. XML has standardized ways of storing dates and times - I would think very carefully before deliberately straying from them. – Jon Skeet Jan 21 '11 at 07:08
  • @Jon: Yeah, I was trying to point out a more generalised way to serialise to/from text losslessly, but I didn't really put it very well - as you say, I've strayed a bit from the point :-) – Jason Williams Jan 21 '11 at 23:25
5

You can use the XmlConvert class to convert to and from strings.

Øyvind Skaar
  • 1,842
  • 14
  • 22