views:

4877

answers:

5

Hi,

I have a string that looks like this: "9/1/2009". I want to convert it to a DateTime object (using C#).

This works:

DateTime.Parse("9/1/2009", new CultureInfo("en-US"));

But I don't understand why this doesn't work:

DateTime.ParseExact("9/1/2009", "M/d/yyyy", null);

There's no word in the date (like "September"), and I know the specific format, so I'd rather use ParseExact (and I don't see why CultureInfo would be needed). But I keep getting the dreaded "String was not recognized as a valid DateTime" exception.

Thanks

A little follow up. Here are 3 approaches that work:

DateTime.ParseExact("9/1/2009", "M'/'d'/'yyyy", null);
DateTime.ParseExact("9/1/2009", "M/d/yyyy", CultureInfo.InvariantCulture);
DateTime.Parse("9/1/2009", new CultureInfo("en-US"));

And here are 3 that don't work:

DateTime.ParseExact("9/1/2009", "M/d/yyyy", CultureInfo.CurrentCulture);
DateTime.ParseExact("9/1/2009", "M/d/yyyy", new CultureInfo("en-US"));
DateTime.ParseExact("9/1/2009", "M/d/yyyy", null);

So, Parse() works with "en-US", but not ParseExact... Unexpected?

+13  A: 

I suspect the problem is the slashes in the format string versus the ones in the data. That's a culture-sensitive date separator character in the format string, and the final argument being null means "use the current culture". If you either escape the slashes ("M'/'d'/'yyyy") or you specify CultureInfo.InvariantCulture, it will be okay.

If anyone's interested in reproducing this:

// Works
DateTime dt = DateTime.ParseExact("9/1/2009", "M'/'d'/'yyyy", 
                                  new CultureInfo("de-DE"));

// Works
DateTime dt = DateTime.ParseExact("9/1/2009", "M/d/yyyy", 
                                  new CultureInfo("en-US"));

// Works
DateTime dt = DateTime.ParseExact("9/1/2009", "M/d/yyyy", 
                                  CultureInfo.InvariantCulture);

// Fails
DateTime dt = DateTime.ParseExact("9/1/2009", "M/d/yyyy", 
                                  new CultureInfo("de-DE"));
Jon Skeet
You're right, either one of those will work. I'm not sure which one I prefer yet. I guess escaping the slashes is more compact...Thanks, this had been nagging me for a while!
Jimmy
I'm not sure why your second example works for you. That doesn't work for me. Using CultureInfo("en-US") works with Parse() for this date string, but does not work with ParseExact with this date string and format string.
Jimmy
@Jimmy: It depends on the intent. In this case, / is used as an exact slash and *not* as a culture-sensitive separator (even when the culture is `InvariantCulture`), so the option that better expresses your intent is the one with quoted slashes (the one you picked).
280Z28
+1  A: 

Try

Date.ParseExact("9/1/2009", "M/d/yyyy", new CultureInfo("en-US"))
Scott
I guess I'd rather use DateTime.Parse("9/1/2009", new CultureInfo("en-US")) then, if I have to specify the culture anyway...?
Jimmy
Rather than instantiating a new instance of CultureInfo("en-US") each time you parse a date, use CultureInfo.InvariantCulture.
Joe
Actually this does NOT work (at least for me?) Using "en-US" works with Parse, but not with ParseExact (for this date and format string)
Jimmy
A: 

try this

provider = new CultureInfo("en-US");
DateTime.ParseExact("9/1/2009", "M/d/yyyy", provider);

Bye.

RRUZ
+1  A: 

I bet your machine's culture is not "en-US". From the documentation:

If provider is a null reference (Nothing in Visual Basic), the current culture is used.

If your current culture is not "en-US", this would explain why it works for me but doesn't work for you and works when you explicitly specify the culture to be "en-US".

Lee
Nah, interestingly enough, CultureInfo.CurrentCulture does return "en-us"... so I'm not sure how to explain why it would work for you but not for me.
Jimmy
I tried a few things. Here's what works:DateTime.ParseExact("9/1/2009", "M'/'d'/'yyyy", null);DateTime.ParseExact("9/1/2009", "M/d/yyyy", CultureInfo.InvariantCulture); DateTime.Parse("9/1/2009", new CultureInfo("en-US"));Here's what doesn't work:DateTime.ParseExact(dateString, "M/d/yyyy", CultureInfo.CurrentCulture); DateTime.ParseExact(dateString, "M/d/yyyy", new CultureInfo("en-US")); DateTime.ParseExact(dateString, "M/d/yyyy", null); So Parse() works with "en-US", but not ParseExact ... interesting huh?
Jimmy
Woops formatting got all screwed up. I'll add to the question.
Jimmy
A: 

I tried it on XP and it doesn't work if the PC is set to International time yyyy-M-d. Place a breakpoint on the line and before it is processed change the date string to use '-' in place of the '/' and you'll find it works. It makes no difference whether you have the CultureInfo or not. Seems strange to be able specify an expercted format only to have the separator ignored.

BigOldSofty