I have been posting a lot about the product – Coded UI Test and Microsoft Test Manager. This is my first post probably on the dev topic. The post is copy\paste of the internal email that I sent to our dev team. You will find this useful if you do Globalization\Localization of your code.
Based on code reviews, I have observed some common coding confusion among devs. The #1 coding confusion is mix up between CultureInfo.InvariantCulture and CultureInfo.CurrentCulture. You will find lots on this on web but none with good examples. Below is my attempt -
What is CultureInfo?
Provides information about a specific culture (called a "locale" for unmanaged code development). The information includes the names for the culture, the writing system, the calendar used, and formatting for dates and sort strings.
This means a date of 27th November 2010, when converted to string could be “11/27/10” or “27/11/2010” or “27-NOV-2010” or something else depending on the culture. Similarly parsing back a string “3.3” as double might succeed (e.g. in en-US) or fail (e.g. Fr-fr as comma ‘,’ and not dot ‘.’ is the decimal separator). So it is important to use right CultureInfo any time you are converting any rich .NET object to string or are parsing string to construct the object.
For example, use CultureInfo in string.Format, XXX.ToString (like DateTime.ToString), XXX.Parse (like int.Parse), XXX.TryParse (like double.TryParse) etc.
What are various CultureInfo’s?
The CultureInfo class has four static CultureInfo properties –
When to use?
A fixed (i.e. invariant) culture info which is based on English and is independent of any region or country or other settings & cannot be changed by the user. (Note that this is not same as en-US.) All objects will give the same string when ToString(CultureInfo.InvariantCulture) is called irrespective of the language, culture, region, country or the customization done by the user.
1. To store, retrieve and manipulate data in non-UI layer like storing\retrieving options from registry\configuration files.
2. To trace\debug or other messages that are for non-end users (like product devs).
Culture information of the current thread based on user’s current culture. This includes the standard culture chosen by the user plus any customization done on top of that (at OS level or within the thread). Because this includes customization done by the user, even for two people having same en-US culture, the data could be different.
1. To parse data coming from the user
2. To show data to the user on the UI or console or data going into the files meant for user.
The user’s culture as represented by standards excluding any customization by user.
There are rare scenarios where one will need these two cultures. It is best to forget them to avoid confusion.
The culture installed with the OS.
Culture to use
Take a double as input from the user
Data coming as an input from the user. Refer example above – in Fr-fr, “,” and not “.” is decimal point separator.
Take a date time filter from the user via a Text Box (like WIT Query) and parse it into date time object
Data coming as an input from the user – she will prefer to give it in her culture.
Show a date time to the user in the UI
Data being shown to the user – makes it easy for the user to understand
Show an error message to the user
Same as above
Trace a message for debugging
Data meant for developer and not the user. You don’t want to wonder what “12/6/2010” means – 6th Dec or 12th June.
Save users last time filter to registry
So that even if user changes her culture, the last time filter option saved in registry works as expected.
Serialize an object into XML to save it on the server (like UITest object)
The client and server culture could be different and the same data could be consumed by another user in different culture.
Mixed Scenario –
Consider WIT like query where the user gives “Created Date < 12/6/2010” in the query and saves it on the server (assume it saves it as XML). Later she opens the same query.
- While saving
- While opening
The above might seem cumbersome – why not store and retrieve the data all along in CurrentCulture? The reason is as mentioned above – a) the client & server cultures could be different & b) there may be multiple users having different culture consuming this data. In fact the same user may have changed her culture between saving and reopening.