Why can't DateTime.ParseExact() parse "9/1/2009" using "M/d/yyyy"
Asked Answered
M

7

63

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?

Mall answered 2/9, 2009 at 16:7 Comment(3)
What version of .NET are you using? When I execute the second line above in PowerShell v2 on Win7, it works just fine.Incantation
I'm using .net 3.5 on xp . The default culture is en-us.Mall
In the string "M/d/yyyy", each slash / is substituted with the culture.DateTimeFormat.DateSeparator string. When you give null as format provider, the current culture is used. Now it depends on whether the current culture has "/" or some other string (like "-" or ".") as its DateSeparator.Government
J
98

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"));
Jasik answered 2/9, 2009 at 16:14 Comment(7)
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!Mall
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.Mall
@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).Rozanna
@Jon one of DateTime.ParseExact argument is the CultureInfo. so if I write :new CultureInfo("de-DE") , it means that I know that date is separated with .. so why I still need to write in format : M/d/yyyy and not M.d.yyyy ? didn't we say that I know that the date is separated with . ?I'm having a difficulty to understand it. if I recognize something by its culture, I know exactly how it should look. BUT if you told me , that the user entered 9@@1@@2009 then I would say - fine. lets use parseExact. but then I wont need culture. can you please help ?Cellule
@RoyiNamir: Sorry, I really don't understand what you're asking.Jasik
:-) Ok. I'll try again.If I'm specifying new CultureInfo("de-DE") it means that I know exactly what are the separators. so Why should I use M/d/yyyy and not M.d.yyyy ? ( I already know that / is a date separator and . is not , but again If i know the structure , it seems meanningless...[/ vs .] )Cellule
@RoyiNamir: You could use either - but I would personally use / as anyone reading it should then understand that it is meant to be the date separator.Jasik
I
3

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".

Incantation answered 2/9, 2009 at 16:20 Comment(2)
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.Mall
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?Mall
D
2

Try

Date.ParseExact("9/1/2009", "M/d/yyyy", new CultureInfo("en-US"))
Duquette answered 2/9, 2009 at 16:15 Comment(3)
I guess I'd rather use DateTime.Parse("9/1/2009", new CultureInfo("en-US")) then, if I have to specify the culture anyway...?Mall
Rather than instantiating a new instance of CultureInfo("en-US") each time you parse a date, use CultureInfo.InvariantCulture.Ludwigg
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)Mall
A
0

try this

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

Bye.

Archy answered 2/9, 2009 at 16:17 Comment(0)
C
-1

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.

Cahoot answered 14/7, 2010 at 23:55 Comment(0)
P
-4

Set DateTimePicker's Format property to custom and CustomFormat prperty to M/dd/yyyy.

Phanotron answered 24/7, 2012 at 20:48 Comment(1)
This question has absolutely nothing to do with DateTimePicker.Trimetric
U
-4

Try :

Configure in web config file

<system.web> <globalization culture="ja-JP" uiCulture="zh-HK" /> </system.web>

eg: DateTime dt = DateTime.ParseExact("08/21/2013", "MM/dd/yyyy", null);

ref url : http://support.microsoft.com/kb/306162/

Upbeat answered 4/3, 2015 at 9:9 Comment(1)
There's nothing in this question that suggests a web application.Chiquia

© 2022 - 2024 — McMap. All rights reserved.