tags:

views:

557

answers:

7

I have a problem with a c# assembly (.net 2.0 written using Visual studio 2005) that is installed on a UK server and should use UK regional settings.

What my code does is to convert a date in the form dd/MM/yyyy into utc. i.e. yyyy-mm-dd. The problem arose with dates like 16/02/2010 where the component failed to convert the date and returned Error. After debugging I realised that, for a strange reason, the CultureInfo returned by System.CultureInfo is en-US.

I can programatically change those settings using:

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB", false); 

and my code works fine.

However I don't want to do that all the time as my system should be UK. Not US. So, how do I change the default culture for .Net framework to be by default en-GB instead of en-US ?

For information:

  • I have tried to update the machine.config file and specify culture=en-GB for the globalization section (it was set to neutral) but it doesn't work either [have done that for 1.1 and 2.0] but it's possible I have not changed it correctly.
  • I have verified my windows regional settings and they are definitely set-up to UK with dates as dd/MM/yyyy
  • I am running in a Virtual server and have verified my host system. It too is set to UK

Edit:

A bit of extra detail about the context. The assembly in question is being called via COM interop from a native C++ third party component that is running as a COM+ application.

+1  A: 

I believe this is represented by System.Globalization.CultureInfo.InstalledUICulture, so if nothing else maybe you can copy that to the thread's current culture. I'm surprised that you found a case where the threads culture is different than the installed culture. Perhaps your code is running in a process that changed the culture?

It is possible the account running the code has different regional settings than the system default. Have you checked that?

BlueMonkMN
I'm not sure the first suggestion is really much different to just setting the culture explicitly. It _is_ possible that the user account is set wrong, I will check.
andynormancx
A: 

To set the UI culture and culture for all pages, add a globalization section to the Web.config file, and then set the uiculture and culture attributes, as shown in the following example:

<globalization uiCulture="en" culture="en-GB" />

garpunkal
The code in question is not running within ASP.NET, so there is no web.config file, I'm guessing that that setting could be set in the app's config file as well though. I'll add some extra detail to the question about the calling context.
andynormancx
+1  A: 

You do not have to change the CurrentCulture to do the transformation. If you are certain that the date is in the form of "dd/MM/yyyy" you could use

DateTime dtTemp = DateTime.ParseExact(dateString, "dd/MM/yyyy", null) // in order not to have to specify a FormatProvider

and then use

dtTemp.ToString("yyyy-MM-dd")

This way you will not have a problem no matter what the CurrentCulture is. However, if you are not certain that the Date is of the form "dd/MM/yyyy" rather it is based on the CurrentCulture short date format, then you should use

DateTime dtTemp = DateTime(dateString, CurrentCulture.DateTimeFormat.ShortDatePattern, CurrentCulture.DateTimeFormat);
Nikos Steiakakis
I like this pragmatic solution to the problem and thinking about it, it is probably the best way to implement it anyway, as the input/output formats really are fixed. I'd still like to know why the system locale isn't working how I expect though.
andynormancx
I came up with this workaround, in a case where the selected locale of the system mandated a format of "dd/MM/yyyy" but the user had selected the date to be formatted as "MM/dd/yyyy". So I could not really trust the current culture. This is possible in Windows 7 and I think in XP as well.
Nikos Steiakakis
+3  A: 

Hmmm, according to the API Docs:

When a thread is started, its culture is initially determined by using GetUserDefaultLCID from the Windows API.

This method derives it's locale from the (as the name implies) User's Default Locale, which I assume is in the Control Panel. NOTE: This is NOT the same as the UI Locale.

Clinton
A: 

Assemblies in .net framework are culture neutral.

What code are you trying to convert the date? If you are using Parse or TryParse, try providing the culture argument for it to understand the date.

shahkalpesh
+1  A: 

The server is not configured correctly. Control Panel + Region and Language, Location tab. Changing this could be a bit tricky. The server may well have been mis-configured on purpose. Talk to the server administrator first before doing anything.

Your fallback plan is to use the DateTime.TryParse() method overload that takes the IFormatProvider argument. Pass CultureInfo.GetCultureInfo("en-gb").DateTimeFormat.

Hans Passant
+1  A: 

hi all,

thanks for your answers (andy posted the question on my behalf). It was indeed an issue with regional settings but neither with the user I was connected under, nor with the user the process was running under. That would have been too easy. It looks like that the default user was still en-US. I did reset by clicking the checkbox "Apply settings to the current user and default user..." in the advanced tab and rebooting the server. System.Globalization.CultureInfo now return {en-GB}. And a MyDate.ToString(yyyy-mm-dd) works fine whether the date is passed as dd/MM/yyyy or dd-MM-yyyy or yyyy-MM-dd without the need to parse.

However thanks you all very much for your suggestions (ParseExact, etc) that did indeed work. They ill be very helpful for other date formats that I was not able to handle in a nice way (yyyyMMdd).

Marc

marc