tags:

views:

1152

answers:

5

I'm having an issue where a specific time string, contained in the Gmail Atom feed isn't parsing using DateTime.Parse(). I understand I could use DateTime.TryParse(), but I'm curious to why these two don't work, where as all of the rest do.

2009-12-28T24:11:48Z
2009-12-30T24:16:20Z

the specific exception is:

System.FormatException: The DateTime represented by the string is not supported in calendar System.Globalization.GregorianCalendar.

My suspicion is that it's because of the hour 24... rather than 00, but I'm not sure how I would rectify that.

A: 

turns out google's using the w3c date and time standard: http://www.w3.org/TR/NOTE-datetime, which c# doesnt support? weird, but not that weird.

this project appears to implement that for you.

http://www.codeproject.com/KB/cs/w3cdate.aspx

edit: yes, I see now that google's not doing it right, but there's an exception for that in the w3cdate c# structure.

Oren Mazor
However, that specification declares "hh = two digits of hour (00 through 23) (am/pm NOT allowed)".
Jeff Sternal
They aren't getting correct though. As the doc linked to says an hour of 24 is not allowed. "hh = two digits of hour (00 through 23) (am/pm NOT allowed)"
Martin Brown
The `24` in the w3 spec you linked isn't allowed `"hh = two digits of hour (00 through 23) (am/pm NOT allowed)"`C# DOES support that standard, but Google is using some other standard or variant. The project you linked does account for it though.
md5sum
you guys are correct, however the w3cdate structure linked has an exception for google in the parse function.
Oren Mazor
A: 

If it IS just the 24 instead of 00, you can simply replace it and add a day:

String s = "2009-12-28T24:11:48Z";
DateTime dt;
if (s.Contains("T24:")
{
    s = s.Replace("T24:", "T00:");

    if (DateTime.TryParse(s, out dt))
        dt.AddDays(1);
}
else
{
    DateTime.TryParse(s, out dt);
}
md5sum
By doing this you would also need to add one to the day probably after passing.
Martin Brown
@Martin - You're right, edited.
md5sum
A: 

The DateTime entry in MSDN says that it supports ISO 8601 which allows both 24 and 00. It should allow the format of type [YYYY][MM][DD]T[hh][mm]Z eg. 2010-01-04T14:04Z.

Midnight is a special case and can be referred to as both "00:00" and "24:00". The notation "00:00" is used at the beginning of a calendar day and is the more frequently used. At the end of a day use "24:00". Note that "2007-04-05T24:00" is the same instant as "2007-04-06T00:00" (see Combined date and time representations below).

jbloomer
Unfortunately that's only talking about 00:00 vs. 24:00 (aka midnight) afaik, that is: That exact moment. 24:17 is quite a bit after that and is invalid as far as I can see.
Benjamin Podszun
I think that it will allow `24:00` but not `24:01`.
md5sum
Yes, you're both right.
jbloomer
A: 

Same idea as md5sum, but a different way:

 DateTime.ParseExact(
  "2009-12-28T24:11:48Z",
  new []{ "yyyy-MM-ddTHH:mm:ssK", "yyyy-MM-ddT24:mm:ssK" }, 
  System.Globalization.CultureInfo.InvariantCulture,
  System.Globalization.DateTimeStyles.None
)

You'd still need to check if the date is correct though.

Benjamin Podszun
date returned is `12/27/2009 6:11:48 PM`... I'd assume the -6 hours is from my time zone, but you still need to add a day.
md5sum
+6  A: 
    private static DateTime ParseDate(string s)
    {
        DateTime result;
        if (!DateTime.TryParse(s, out result))
        {                
            result = DateTime.ParseExact(s, "yyyy-MM-ddT24:mm:ssK", System.Globalization.CultureInfo.InvariantCulture);
            result = result.AddDays(1);
        }
        return result;
    }
Martin Brown
Nice mashup ;) +1
Benjamin Podszun
Oh heck yah! +1
md5sum
fantastic. Thank you very much :)
Alastair Pitts