-1

I'm parsing a date string from a database so that I can display it in the current culture of the UI thread. For some reason, the date is not parsing with respect to the culture - specifically, I'm parsing a en-US date to switch to a es-ES date and the month/day positions are not switching.

According to this MSDN article I should just be able to use Parse with only the date string as a parameter. I should also be able to explicitly provide a culture object. Neither works and my date remains as mm/dd instead of dd/mm. I've verified that both the thread's CurrentCulture and CurrentUICulture are set properly and if I do a new DateTime, that outputs correctly.

Am I missing something?

EDIT: Nothing fancy in the code, just the .NET API.

CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureName);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
DateTime formattedDate = DateTime.Parse("5/9/2014");
formattedDate.ToShortDateString(); //this returns 5/9/2014
DateTime.Today.ToShortDateString(); //this returns 9/5/2014
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Shawn Hubbard
  • 932
  • 10
  • 23

2 Answers2

3

The problem you are having is that 5/9/2014 is a perfectly valid month string in either dd/mm/yyyy or mm/dd/yyyy format so when you do DateTime.Parse("5/9/2014") it will successfully parse it as 5th September 2014 (since the es-es date format is dd/mm/yyyy).

This then explains why when you output you get something different to DateTime.Today (which is obviously 9th May).

A working version of your program would be:

var outputCulture = CultureInfo.CreateSpecificCulture("es-es");
var inputCulture = CultureInfo.CreateSpecificCulture("en-us");
Thread.CurrentThread.CurrentCulture = outputCulture;
Thread.CurrentThread.CurrentUICulture = outputCulture;
DateTime formattedDate = DateTime.Parse("5/9/2014", inputCulture);
Console.WriteLine(formattedDate.ToShortDateString()); //this returns 09/05/2014
Console.WriteLine(DateTime.Today.ToShortDateString()); //this returns 09/05/2014

As you see I am specifying the culture for input so that it knows to use the en-us culture rather than the explicitly set es-es culture for parsing.

Chris
  • 27,210
  • 6
  • 71
  • 92
  • That makes sense. I wasn't thinking of needing to specify both the fact that I know it's coming in as US and going out as the thread culture. Thanks! – Shawn Hubbard May 09 '14 at 14:29
  • Easy to miss if you haven't done it a hundred times before. ;-) And this is exactly why a little program to reproduce the error is so nice because it allows us to see exactly what assumptions you have made and made it super easy for me to test my theory and give you a fixed demo. :) – Chris May 09 '14 at 14:35
  • Well, in truth, the part of our app setting thread culture is somewhere else entirely. My code literally was just DateTime.Parse. Either way, thanks for the approach - it makes perfect sense now. – Shawn Hubbard May 09 '14 at 14:40
0

Since you are parsing a string from a database, the only way to do this correctly is to persist the string in a standard format that does not depend on any culture specific data. ISO 8601 defines formats appropriate for this and you can use a custom format string to achieve this. You can also use .Net's 'o' format specifier for round trip. See How to: Round-trip Date and Time Values for more information.

Culture specific settings do change and cause items that used to parse, to no longer be able to parse even if you know the culture that was used to format the value with to start with.

Culture specific formatting and parsing is meant to be ephemeral and to be used to interact with the user only.

Eric MSFT
  • 3,246
  • 1
  • 18
  • 28
  • This is the solution we will move to eventually, but for the time being the process storing the date is all built without localization in mind so I needed a shorter-term solution. – Shawn Hubbard May 09 '14 at 22:19