Why can't DateTime.ParseExact parse DateTime output?
While struggling with DateTime.ParseExact formatting issues, I decided to feed ParseExact the out put from DateTime.ToString(), like this:
DateTime date2 = new DateTime(1962, 1, 27);
string[] expectedFormats = { "G", "g", "f", "F", "D", "d", "M/d/yyy", "MM/dd/yyy", "MM-dd-yyy", "MMM dd, yyy", "MMM dd yyy", "MMMM dd, yyy", "MMMM dd yyy" };
bool parsed = false;
foreach (string fmt in expectedFormats)
{
try
{
DateTime dtDateTime = DateTime.ParseExact(date2.ToString(fmt), fmt, new CultureInfo("en-US"));
parsed = true;
}
catch (Exception)
{
parsed = false;
}
Console.WriteLine("[{0}] {1}", parsed,date2.ToString(fmt));
}
This is the output:
[True] 1/27/1962 12:00:00 AM
[True] 1/27/1962 12:00 AM
[True] Saturday, January 27, 1962 12:00 AM
[True] Saturday, January 27, 1962 12:00:00 AM
[True] Saturday, January 27, 1962
[True] 1/27/1962
[False] 1/27/1962
[False] 01/27/1962
[False] 0开发者_JS百科1-27-1962
[False] Jan 27, 1962
[False] Jan 27 1962
[False] January 27, 1962
[False] January 27 1962
What do I have to do so that ParseExact will parse the custom format strings? Am I wrong to expect DateTime to be able to ingest it's own output based on the same format string?
This clearly demonstrates that DateTime.ParseExact
is not round-trip safe with Datetime.ToString
. I am not sure this is much of an answer, but the problem is definitely related to the 3 digit year format yyy
. Since 1962 cannot be represented in 3 digits ToString
is forced to use 4 digits. Apparently ParseExact
is not smart enough to reverse that logic and instead is looking for exactly 3 digits. The workaround is to use yyyy
instead of yyy
. I would submit this as a bug to the Microsoft Connect website and see what comes of it.
I'm suprised seeing this, but the documentation at msdn says:
You can specify one of the standard date and time format specifiers or a limited combination of the custom date and time format specifier
http://msdn.microsoft.com/en-us/library/2h3syy57.aspx
Update
You can use the workaround mentioned in the previous answer.
I took your code, and changing "yyy" to "yyyy" is enough to return "TRUE" for them all (having first reproduced the "FALSE"s before I made any changes).
The documentation at MSDN is unclear, but does emphasize the need for specifying the full width of every component (e.g. yyyy rather than yyy) without the invariant culture:
http://msdn.microsoft.com/en-us/library/w2sa9yss.aspx
If format is a custom format pattern that does not include date or time separators (such as "yyyyMMdd HHmm"), 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 format pattern, specify the wider form, "HH", instead of the narrower form, "H".
Microsoft has implemented a string format for round-tripping a DateTime. You use the "o" or "O" format.
You will need to set the styles parameter in DateTime.ParseExact to DateTimeStyles.RoundtripKind.
For full details see: http://msdn.microsoft.com/en-us/library/az4se3k1%28v=vs.110%29.aspx#Roundtrip
精彩评论