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?

Jimmy
  • 5,131
  • 9
  • 55
  • 81
  • What version of .NET are you using? When I execute the second line above in PowerShell v2 on Win7, it works just fine. – Lee Sep 02 '09 at 16:10
  • I'm using .net 3.5 on xp . The default culture is en-us. – Jimmy Sep 02 '09 at 16:29
  • 1
    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`](http://msdn.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.dateseparator.aspx). – Jeppe Stig Nielsen Feb 20 '14 at 10:44

7 Answers7

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"));
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 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 Sep 02 '09 at 16:30
  • 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 Sep 02 '09 at 16:49
  • 1
    @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). – Sam Harwell Sep 02 '09 at 16:49
  • @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 ? – Royi Namir Feb 17 '13 at 13:11
  • @RoyiNamir: Sorry, I really don't understand what you're asking. – Jon Skeet Feb 17 '13 at 13:27
  • :-) 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 `.`] ) – Royi Namir Feb 17 '13 at 13:58
  • @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. – Jon Skeet Feb 17 '13 at 14:36
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".

Lee
  • 18,529
  • 6
  • 58
  • 60
  • 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 Sep 02 '09 at 16:33
  • 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 Sep 02 '09 at 16:43
2

Try

Date.ParseExact("9/1/2009", "M/d/yyyy", new CultureInfo("en-US"))
Dan McClain
  • 11,780
  • 9
  • 47
  • 67
Scott
  • 11,046
  • 10
  • 51
  • 83
  • 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 Sep 02 '09 at 16:31
  • Rather than instantiating a new instance of CultureInfo("en-US") each time you parse a date, use CultureInfo.InvariantCulture. – Joe Sep 02 '09 at 16:36
  • 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 Sep 02 '09 at 16:47
0

try this

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

Bye.

RRUZ
  • 134,889
  • 20
  • 356
  • 483
-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.

-4

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

Himanshu
  • 31,810
  • 31
  • 111
  • 133
-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/

RINESH KM
  • 1
  • 3