4

I have a date string that is coming in as what I believe to be Mddyyyy. However, TryParseExact doesn't seem to be working. Here's the sample code that fails:

string datestring = "1212012";

DateTime td;
if (DateTime.TryParseExact(datestring, "Mddyyyy", new CultureInfo("en-US"),     DateTimeStyles.None, out td))
{
    Console.WriteLine(td.ToShortDateString());
}
else
{
    Console.WriteLine("Invalid Date String");
}

That same code works if there's a leading zero, but I would think then that the leading zero would only work with a formatting string of MMddyyyy.

Odrade
  • 7,409
  • 11
  • 42
  • 65
Devin Goble
  • 2,639
  • 4
  • 30
  • 44
  • 5
    Hint: Is your example date January 21st 2012 or December 1st 2012? Also, we appreciate the actual question in your posting (though I think it's safe to assume you are asking "How do I make TryParseExact parse this date?") – Chris Shain Mar 09 '12 at 23:30
  • I see the ambiguity, but does that mean that the January dates with days in the 10-29 range are unparseable by DateTime when given in the Mddyyyy format? I realize that you shouldn't use this format for dates, but I'm curious. – Odrade Mar 09 '12 at 23:37
  • Most likely, yes. You can fix this by padding left with zero. The likely reason is the structure of the parser or regular expression used by TryParseExact. The leading M implies a variable number of initial digits specifying the month, with a correct decision path that is only knowable by looking at the total length of the string. I'd bet the parser just isn't that sophisticated, though I'll admit I haven't looked. – Chris Shain Mar 09 '12 at 23:42
  • Thanks, I adjusted the title. So, is the best course to do some custom parsing on my own? I realize that it's not necessarily the right way to express dates, as Odrade said, but it's what I have to work with. – Devin Goble Mar 10 '12 at 00:15
  • 3
    If a human can't figure out what date that might be, it's safe to assume that a machine can't either. But yes, write your custom parser to discover this yourself. – Hans Passant Mar 10 '12 at 00:16
  • The right way to fix it is to first validate that the dates are indeed in Mddyyyy, and if they are **and they pad their days with zero**, call PadLeft on them to add that leading zero when it isn't there before parsing them the way you already are. If they don't pad their days with zero either then they are actually ambiguous and cannot be parsed by man or machine. – Chris Shain Mar 10 '12 at 00:30
  • Only variable length is 'M'; dd and yyyy are fixed length of 2 and 4 digits, as order is given by the format string and 'M' allows either 1 or 2 digits it 'should' parse correctly i'd say. – nik Mar 10 '12 at 00:36
  • 1
    similar question: http://stackoverflow.com/questions/3551283/parse-simple-datetime – John Pick Mar 10 '12 at 00:48

1 Answers1

3

Here I propose an explanation and provide evidence for the proposal.

Proposed Explanation: The parser internally uses the format string to create a regular expression that contains a greedy quantifier (which means, in this case, it prefers to match 2-digit months over 1-digit months). The M in the OP's format string becomes something like \d{1,2} (though that would match months numbered from 0 to 99!) in the parser's internal regular expression.

Evidence: If you move the month to the end of both the data and the format string, the greedy quantifier cannot obtain more than 1 digit and so it matches the month as desired:

string datestring = "2120121";

DateTime td;
if (DateTime.TryParseExact(datestring, "ddyyyyM", new CultureInfo("en-US"), DateTimeStyles.None, out td))
{
    Console.WriteLine(td.ToShortDateString());
}
else
{
    Console.WriteLine("Invalid Date String");
}

Bottom Line: Don't rely on undocumented behavior. Always use unambiguous data, i.e., 2-digit months.

John Pick
  • 5,562
  • 31
  • 31
  • I have finally had a chance to look into the parsing code itself- while this isn't a precise answer (because no regex is actually used) it is functionally accurate, and I agree with the bottom line. – Chris Shain Mar 10 '12 at 05:58
  • yes, the IL. Using reflector you can see it as something similar to the original C# – Chris Shain Mar 10 '12 at 13:36