I\'m trying out the DateTime.TryParseExact
method, and I have come over a case that I just don\'t get. I have some formats and some subjects to parse that each
If you do not use date or time separators in a custom format pattern, use the invariant culture for the provider parameter and the widest form of each custom format specifier. For example, if you want to specify hours in the pattern, specify the wider form, "HH", instead of the narrower form, "H"
cite: http://msdn.microsoft.com/en-us/library/ms131044.aspx
As others have pointed out H is ambiguous because it implies a 10 hour day, where as HH is 12
I could be wrong, but I suspect it may have to do with the ambiguity inherent in the "H" part of your format string -- i.e., given the string "123", you could be dealing with hour "1" (01:00) or hour "12" (12:00); and since TryParseExact
doesn't know which is correct, it returns false.
As for why the method does not supply a "best guess": the documentation is not on your side on this one, I'm afraid. From the MSDN documentation on DateTime.TryParse (emphasis mine):
When this method returns, contains the
DateTime
value equivalent to the date and time contained in s, if the conversion succeeded, orDateTime.MinValue
if the conversion failed. The conversion fails if either the s or format parameter isnull
, is an empty string, or does not contain a date and time that correspond to the pattern specified in format. This parameter is passed uninitialized.
Ok, so I think I have figured this all out now thanks to more reading, experimenting and the other helpful answers here. What's happening is that H, m and s actually grabs two digits when they can, even if there won't be enough digits for the rest of the format. So for example with the format Hmm and the digits 123, H would grab 12 and there would only be a 3 left. And mm requires two digits, so it fails. Tadaa.
So, my solution is currently to instead use just the following three formats:
var formats = new[]
{
"%H",
"Hm",
"Hms",
};
With the rest of the code from my question staying the same, I will then get this as a result:
1 : 01:00:00
12 : 12:00:00
123 : 12:03:00
1234 : 12:34:00
12345 : 12:34:05
123456 : 12:34:56
Which I think should be both reasonable and acceptable :)
0123 012345
I'm guessing it looks for a length of 2/4/6 when it finds a string of numbers like that. Is 123 supposed to be AM or PM? 0123 isn't ambiguous like that.
To quote from MSDN's Using Single Custom Format Specifiers:
A custom date and time format string consists of two or more characters. For example, if the format string consists only of the specifier h, the format string is interpreted as a standard date and time format specifier. However, in this particular case, an exception is thrown because there is no h standard date and time format specifier.
To use a single custom date and time format specifier, include a space before or after the date and time specifier, or include a percent (%) format specifier before the single custom date and time specifier. For example, the format strings "h " and "%h" are interpreted as custom date and time format strings that display the hour represented by the current date and time value. Note that, if a space is used, it appears as a literal character in the result string.
So, should that have been % H
in the first element in the formats
array?
Hope this helps, Best regards, Tom.
"123" and "12345" seem to be ambiguous with respect to the TryParseExact method. "12345" could be either 12:34:50 or 01:23:45 for instance. Just a guess though.