locked
DateTime UniversalSortableDateTimePattern conversion problems RRS feed

  • Question

  • I apologize if this is the wrong area or a question that has already been answered, I'm new to this forum so please forgive me.

    Having said that I have a question about date and time conversion using the DateTime class.

    Intuitively I would think that any conversion to and from a string should be symmetrical.  That is to say:

    DateTime myNewDateTime = new DateTime.Parse(someDateTime.ToString(...));

    with a predefined string format (not a custom one) should always return with myNewDateTime equal to someDateTime (excluding any strange month/day swapping problems).

    However using the UniversalSortableDateTimePattern returns unusual results for me.  That is to say:

    DateTime myNewDateTime = new DateTime.Parse(someDateTime.ToString("u"));

    Does NOT return the same DateTime as was input.  This is because the ToString("u") simply appends "Z" to the local date time, however Parse interprets any string ending with "Z" to be in UTC.  So myNewDateTime is off from someDateTime by the time zone difference to UTC.

    I would think that either Parse should be treating a string ending with "Z" as local, OR .ToString("u") should convert to UTC if it is going to append the "Z".  Either way one of the two seems broken to me.  At the very least the documentation should have a disclaimer about that.

    Thoughts?
    Monday, April 6, 2009 7:17 PM

Answers

  • The documentation does say:

    [quote]
    Formatting does not convert the time zone for the date and time object. Therefore, the application must convert a date and time to Coordinated Universal Time (UTC) before using this format specifier.
    [/quote]

    The following demonstrates how it will work if you call ToUniversalTime().  The use of SpecifyKind is a good practice so that processing a DateTime with Kind = DateTimeKind.Unspecified is avoided.  This particular example will work correctly if those calls are omitted.  Not all code that works with dates and times is so forgiving.

                DateTime d = DateTime.SpecifyKind(new DateTime(2009, 4, 6, 18, 50, 00), DateTimeKind.Local);
    
                string s = d.ToUniversalTime().ToString("u");
    
                DateTime d2 = DateTime.SpecifyKind(DateTime.ParseExact(s, "u", null), DateTimeKind.Utc);
    
                if (d.ToUniversalTime() == d2)
                    Console.WriteLine("OK"); // Prints OK
    Also check out the similar format "o" (round-trip date/time pattern).  It observes the Kind property of the DateTime to determine whether or not it writes out the Z designation.  As the name suggests, it will round trip correctly. 

    I don't disagree that this is a potential pitfall, but it is one of many.  Testing is a must when working with time zones.

    • Proposed as answer by Guo Surfer Wednesday, April 8, 2009 6:48 AM
    • Marked as answer by Guo Surfer Thursday, April 9, 2009 3:47 AM
    Monday, April 6, 2009 11:04 PM