CultureInfo("fr-BE") different on Windows 8.1 than before - c#

I set the culture for an .NET web app in order to use specific format for numbers, currency and date:
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("fr-BE");
On an Windows 2008 server machine with IIS 7 I get "d/m/yy" as short date format (what I want).
On my (new) Windows 8.1 pro machine (developer and test) I get "d-m-yy" format for the same CultureInfo..."dash" instead of "slash" separator.
I've checked also in Control Panel -> Region and the settings for French(Belgium) are as mentioned above, different in W2k8 server than in W8.1pro...
The .NET version is 4, which is ok. Invariant culture doesn't help, as far as I need specific culture to display in the UI and the problem was there. It is true, changes came with Windows 8... Finally I used to override some settings for the Thread culture, like the Date Separator:
DateTimeFormatInfo dtfi = Thread.CurrentThread.CurrentCulture.DateTimeFormat; if (dtfi.DateSeparator != "/") dtfi.DateSeparator = "/";
This ensure that slash will be the date separator all the time in the current thread.
Thank you.
Does anybody knows about it? Belgium changed national standards? Or, Microsoft did for them? Any idea?
Thanks.

Thanks for the answers. .NET version is 4, which is ok. Invariant culture doesn't help, as far as I need specific culture to display in the UI and the problem was there. It is true, changes came with Windows 8...
Finally I used to override some settings for the Thread culture, like the Date Separator:
DateTimeFormatInfo dtfi = Thread.CurrentThread.CurrentCulture.DateTimeFormat;
if (dtfi.DateSeparator != "/") dtfi.DateSeparator = "/";
This ensure that slash will be the date separator all the time in the current thread.
Thank you.

I was looking at similar issue for CultureInfo 'en-NZ', as it been changed for the same culture setting in different Windows version, and cause my web service saved different strings for the same CultureInfo, and it turns out it is provided by Windows since .Net Framework 4, and was a combination of Windows and .Net before that.
Lucky for me, I can make use of Invariant culture, which was recommended by Microsoft to make sure the string I saved into Database not going to be changed because of Windows or future .Net Framework update. The thing is, for my case it was the AM\PMDesignator changed from a.m.\p.m. to AM\PM, and the Invariant culture will make sure it saves to AM\PM I assume it will not change in the future, but if I want it save to a.m.\p.m. as it was for older version of Windows, Invariant culture wouldn't be able to do that, I will probably need define my own custom culture or overwrite the current culture as you did.
See the other question about Microsoft specified that CultureInof are subject to change without notice

Related

Inconsistent DecimalSeparator value

When I apply toString() on a number of type double, I get the string with . as the decimal separator. In one of my projects only, I get , as the decimal separator.
I have not changed CultureInfo data. My CurrentCulture is el-GR in all my projects which is the default system Culture. el-GR uses , as the decimal separator but I have changed this value through Windows Regional Settings to . which is reflected correctly to all my projects except the one in question.
The only difference I can tell is that it is a Web Site and not a usual Visual Studio Project. I do not know if this forces Visual Studio NOT to take into account the local computer NumberFormat exceptions and if/how this can be changed.
The CultureInfo your program use, if you don't explicitly set it somehow in code, is related to Regional Settings of current user.
When running a web project, very likely current user is not you, the one logged in in the computer, but a built-in user IIS uses. see this question and display somehow current user to find out if your problem is actually related to this.
To change regional settings for your (.Net & IIS hosted) web application, you can use different method: web.config of your application, web.config of the whole server, settings for IIS, or even tweak the registry.
Have a look at this thread (and also linked threads you find in the left column) for methods you can use.

.ToShortDateString returning different cultural format than expected

Here's a weird one for you.
We've got a c# interface that's been running since the beginning of the year without problem on a windows XP (32bit) PC. We've just upgraded the PC to windows 7 (64bit) with apps installed by SCCM.
With the latest run the dates in the text area have started appearing in US format (5/2/2014) instead of UK format (02/05/2014).
The code that is being used is:
string Lines = FromFormat.Text + " from " + FromFormat.Charge_From.ToShortDateString() + " to " + FromFormat.Charge_To.ToShortDateString() +".";
Where FromFormat is an object with the source data, Charge_From & Charge_To are DataTime variables.
We've checked the PC's regional settings and created a little test app to display the pc's settings from .Net both of these are set as UK formats
Code for test app:
label1.Text = DateTime.Now.ToString();
label2.Text = DateTime.Now.ToString("dd MMM yyyy");
label3.Text = DateTime.Now.ToShortDateString();
label4.Text = Thread.CurrentThread.CurrentCulture.EnglishName;
I know that I can replace the ToShortDateString() with a ToString("dd/MM/yyyy") to force the correct format but my question is why is this happening?
Is it something to do with the windows 7 upgrade? or the SCCM?
Thanks in advance
ToShortDateString method uses ShortDatePattern property which is identical of "d" standard date and time format of your CurrentCulture.
en-GB culture's ShortDatePattern property is dd/MM/yyyy.
But en-US culture's ShortDatePattern property is M/d/yyyy.
That's why you can't always replace with ToShortDateString and ToString("dd/MM/yyyy"). They are not always the same. And "/" Custom Format Specifier has a special meaning as replace me with the current culture or specified culture's date separator.
I suspect your regional settings changed on your upgrade process and that's why ToShortDateString method generates different results.
But since you didn't tell us your CurrentCulture, we never know what the real problem is..
After much testing and scratching of heads we think we've found an answer to this.
During the testing we noticed that PC’s that had had the interface installed via SCCM (windows 7 only) were producing the US date formatted text but those that were via Click Once directly (predominantly XP) were producing UK date formatted text.
Further testing confirmed that if we installed a Windows 7 PC via Click Once we got UK date formatted text.
Following a lot of confusion, we noticed that when SCCM installed the interface it was installing the RTM version of the Report Viewer but when Click Once was installing the interface the SP1 version of the Report Viewer was installed.
We altered the SCCM to install Report Viewer SP1 and tested a new SCCM installed version of the interface and got UK dates.
Why the version of Report Viewer would affect the culture settings of a PC or how ToShortDateString() works, we have no idea but this appears to be what the issue is.

changing the system time format on windows 7

Well I am looking for a method to change the default windows 7 time format for a system.
So if a system uses like 10PM or 10 AM as default time notation, then i like to change that system to 10:00 or 22:00.
I know how to do it through the GUI, but in my case our software (C#) has to check if time notation is OK and if it is not change it by usage of
C#, registry editing, vbscript, commanline or Powershell, or some specific .exe file
The software we wrote allready makes usage of external progs / languages (vbscript/powershell).
But the problem is so far i have not found a method to do this other then taking over a remote screen.
Perhaps someone knows how to do this ?
The same counts for time zone, and date notation.
You may change the system time format using following code:
RegistryKey rk = Registry.CurrentUser.OpenSubKey(#"Control Panel\International", true);
rk.SetValue("sTimeFormat", "hh:mm:ss"); // HH for 24hrs, hh for 12 hrs
But IMO, this would not be a good practice for an application to change the system user's settings without the consent of the user.
I found this link that shows it being done via vb.net but you would have to translate it. or you could compile this to an exe and run it from a shell. http://www.access-programmers.co.uk/forums/showthread.php?t=152624
The property way to do this in .NET is with code such as the following:
CultureInfo newCultureInfo = (CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone();
newCultureInfo.DateTimeFormat.ShortDatePattern = shortDateFormat;
newCultureInfo.DateTimeFormat.LongTimePattern = longTimeFormat;
Thread.CurrentThread.CurrentCulture = newCultureInfo;
Regarding the solution using the "Control Panel\International" registry key (sorry, can't comment due to not have a 50 reputation):
This doesn't appear to affect the existing process, only new processes created after changing the registry. And obviously code assuming registry values (i.e. implementation details) could break in a future version of windows.
Also the code should Dispose the RegistryKey object. It would be better written with a using block.
Regarding if you should do this, while it would be unlikely an app would want to change the time date format (maybe an app that's an improved way of setting system info), it would be very reasonable to need to do this in an automated test. It's a common bug for code to depend on the default time/date format, so setting them to non-default values, or testing code with various time/date formats could be a good idea.

Convert.ToDouble("4089.90") outputs 40.899,00 why?

I am developing a software that uses number precision, but I have this problem, it happens that when I take a string to convert to double it outputs me with a different culture.
For example I use
Convert.ToDouble("4089.90"); // it outputs 40.899,00
Is strange cause in my computer it works OK but on the client's PC (with the same culture in regional settings) shows me the latter output. I know I can fix it using
Convert.ToDouble("4089.90", System.Globalization.CultureInfo.InvariantCulture);
But there is a lot of code in the program using "Convert.ToDouble" and I wouldn't like to change all of it, on the other hand I want to understand why this happens.
You can set the culture for your thread with:
Thread.CurrentThread.CurrentCulture =
System.Globalization.CultureInfo.InvariantCulture;
You don't say where you are based, but the output is consistent with the current culture being one that has "." as the thousands separator and a decimal comma rather than a decimal point.
However, you state that the culture is the same - which contradicts this. Have you or the client changed (or customised) the "Standards and formats" on the Regional and Language Options? If the setting has been customised it will still read as "English (United Kingdom)" (or where ever) but will produce different results to the default.
I know neither c# nor asp.net, but I think the problem is this: You are performing the operation in a culture where the dot . is the thousands separator and not the decimal separator. The very output you quote is the proof: 40.899,00.
What culture/locale are you working in?
Culture could be based on where the ASP.Net application is running, and not the client PC that is running the browser. While their desktop PC might have similar culture settings, the server may differ.
It is your computer that is not giving the correct answer, not theirs. Your culture states that "4089.90" is the same as 4089900, since the dot (.) is used for separating thousands (and thus there should be three numbers after the dot).
It appears you want to use the dot as a decimal-separator, contrary to your culture settings; so you have to use System.Globalization.CultureInfo.InvariantCulture in your program. Sorry.
Actually is very rare this behaviour cause all the machines have the same culture settings, however I think that the best solution would be to modify the web.config like this:
configuration>
<system.web>
<globalization culture = "es-HN" />
</system.web>
</configuration
And apply the settings for the entire application.
Thanx everyone for your assistance.

How does a .NET process get the culture information?

I have a Windows service running (C#, .NET 2.0) on Windows Server 2003 R2. In one server the System.Threading.Thread.CurrentThread.CurrentCulture is {en-AU} and in the other {en-US}.
This has caused a difference when calling ToString() on a DateTime object. I want the culture to be {en-AU}.
I checked the "Regional and Language Setting". In both servers, the "Regional Options" tab shows "English (Asutralia)". But in the "Advanced" tab it shows "English (United States)" for one and "English (Australia)" for the other. So this must be causing the difference. Although I want to know why exactly the "Advanced" tab says "the language version of the non-unicode programs you want to use", I thought .NET processes were Unicode and should not be affected by this.
How does the .NET runtime determine the culture to use? Any detailed reference would be helpful.
If a culture has not been set on the thread, Thread.CurrentThread.CurrentCulture defaults to the "user default culture" - which it gets from the underlying OS. This is determined by the Formats section in the regional control panel applet.
For a service, it has no control panel settings by default like for a user (the case above) as it runs under the LocalSystem account which will not have a profile, so it uses the system locale from the OS. I'm not sure if this can be set for a service by adjusting the settings in Windows.
There are a few things you could do:
you can explicitly set the CurrentCulture of the main thread when the service starts. If you do this, you will need to bear in mind that any new threads that are created in your service will also need to have their CurrentCulture set as well, as threads do not inherit their culture from parent threads.
you can set the service to run as a specific user, and set that user's regional settings (the formats section) to be the culture you want to use. When the service starts as that use,it will use that user's regional settings.
since your problem seems to be related to calling DateTime.ToString(), make sure you pass the AU culture to the ToString() method:
DateTime.ToString(new CultureInfo("en-AU"))
You could add this as an extension method to save you having to do this everywhere:
public static string ToAUString(this DateTime dateTime)
{
return dateTime.ToString(new CultureInfo("en-AU"));
}
You can then call DateTime.ToAUString() to get the correct output.
In my case it took only one line of code to change the Culture:
System.Globalization.CultureInfo.DefaultThreadCurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo( "en-US" )
It changes default Culture of Main thread and new ones as well.
This MSDN page on CultureInfo has some information that might be relevant:
The user might choose to override some of the values associated with the current culture of Windows through the regional and language options portion of Control Panel. For example, the user might choose to display the date in a different format or to use a currency other than the default for the culture. In general, your applications should honor these user overrides.
If UseUserOverride is true and the specified culture matches the current culture of Windows, the CultureInfo uses those overrides, including user settings for the properties of the DateTimeFormatInfo instance returned by the DateTimeFormat property, and the properties of the NumberFormatInfo instance returned by the NumberFormat property. If the user settings are incompatible with the culture associated with the CultureInfo, for example, if the selected calendar is not one of the OptionalCalendars, the results of the methods and the values of the properties are undefined.
I think this might be a good starting point for your investigations.

Categories

Resources