I was trying to get the number format in order to convert from string to decimal using the current culture, I have the next configuration in my system:
I would like use the current culture info, but using the customize format like the decimal symbol, digit grouping symbol, etc.
Is it there a way to recover the customize format configuration?
Windows allows users to override the standard property values of the
CultureInfo object and its associated objects by using Regional and
Language Options in Control Panel. The CultureInfo object returned by
the CurrentCulture property reflects these user overrides in the
following cases:
If the current thread culture is set implicitly by the Windows
GetUserDefaultLocaleName function.
If the current thread culture
defined by the DefaultThreadCurrentCulture property corresponds to
the current Windows system culture.
If the current thread culture is
set explicitly to a culture returned by the CreateSpecificCulture
method, and that culture corresponds to the current Windows system
culture.
If the current thread culture is set explicitly to a culture
instantiated by the CultureInfo(String) constructor, and that culture
corresponds to the current Windows system culture.
When you pass CurrentCulture, it will be used to pass the string to a decimal.
decimal number;
if (!decimal.TryParse(numberString, NumberStyles.Number, CultureInfo.CurrentCulture, out number))
{
// Something wrong...
}
You can take current Culture Number Format from the CurrentThread.
var format = Thread.CurrentThread.CurrentCulture.NumberFormat;
EDIT:
CultureInfo.NumberFormat
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.
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.
So var decimalDigits = format.NumberDecimalDigits; should return your custom changes.
Related
According to documentation Formatting Date and Time for a Specific Culture
The DateTime structure provides methods that allow your applications to perform culture-sensitive operations on a DateTime type. An application can use the DateTimeFormatInfo class to format and display a DateTime type based on culture. For example, using DateTimeFormatInfo.ShortDatePattern, the date February 1, 2001 can be formatted as 2/1/2001 for the English (United States), "en-US", culture and 01/02/2001 for the English (United Kingdom), "en-GB", culture.
An DateTimeFormatInfo object can be created for a specific culture or for the invariant culture, but not for a neutral culture. A neutral culture does not provide enough information to display the correct date format. An exception is thrown if the application attempts to create a DateTimeFormatInfo object using a neutral culture.
But how come the following does not throw an exception? And where does it get information on how to format date, since specific culture was not specified?
Console.WriteLine(DateTime.Now.ToString("d", new CultureInfo("fr")));
Update:
You can create instances of specific culture or neutral culture,
for example new CultureInfo("fr-FR") or new CultureInfo("fr").
In DateTime.ToString method it says
The ToString(String) method returns the string representation of a date and time value in a specific format that uses the formatting conventions of the current culture; for more information, see CultureInfo.CurrentCulture.
And CultureInfo documentation says
The CultureInfo object that is returned by this property and its associated objects determine the default format for dates, times, numbers, currency values, the sorting order of text, casing conventions, and string comparisons.
Update 2
Yes, so the MSDN page referenced above is outdated and the framework behaviour has changed.
I have the following code
var culture = new CultureInfo("en");
Console.WriteLine(DateTime.Now.ToString("d", culture));
When I run this code targeting .NET 3.0 I get the following exception. But it works well on .NET 4.6.2.
An unhandled exception of type 'System.NotSupportedException' occurred in mscorlib.dll
Additional information: Culture 'en' is a neutral culture. It cannot be used in formatting and parsing and therefore cannot be set as the thread's current culture.
So, going back to my original question. When I use neutral culture, where does the information about DateTime format come from?
From the most recent version of the MSDN doc on DateTimeFormatInfo:
However, a neutral culture lacks culture-specific formatting information, because it is independent of a specific country/region. Instead of populating the DateTimeFormatInfo object with generic values, the .NET Framework returns a DateTimeFormatInfo object that reflects the formatting conventions of a specific culture that is a child of the neutral culture. For example, the DateTimeFormatInfo object for the neutral en culture reflects the formatting conventions of the en-US culture, and the DateTimeFormatInfo object for the fr culture reflects the formatting conventions of the fr-FR culture.
This is also described in the What's New in Globalization and Localization article for .NET 4:
Previous versions of the .NET Framework threw an exception if applications tried to access neutral culture properties such as DateTimeFormatInfo.FirstDayOfWeek. In the .NET Framework 4, neutral culture properties return values that reflect the specific culture that is most dominant for that neutral culture. For example, the French neutral locale retrieves the values of most of its properties from French (France). The FirstDayOfWeek property returns DayOfWeek.Monday, which reflects the value of that property in the French (France) culture.
I am currently fixing FxCop issues so I encountered issue where I have to provide cultureinfo when converting a string using ToString() .
Currently in my code nothing we are passing as IFormatProvider so I have read some msdn articles saying that when you don't pass any value for cultureinfo it will assign a default value and when you specify CultureInfo as InvariantCulture it will be independent of any culture.
My question is, "Are default and CultureInfo.InvariantCulture one and the same? Can I replace all my code from default to InvariantCulture?"
Ex :
int st = 123;
String s = st.ToString(123); // this will be taken as default
String s = st.ToString(123, CultureInfo.InvariantCulture); // culture is specified externally
Are the second and third lines equivalent?
Is default and CultureInfo.InvariantCulture are one and the same?
No, absolutely not. The default culture depends (initially) on the operating system settings. The invariant culture is meant to be a "neutral" culture.
Your example of 123 isn't a great one, because most (all?) cultures will represent integers the same way - at least until you get into formats with grouping separators etc. (I don't think .NET supports non-Arabic numerals when formatting integers.)
Compare that with formatting a decimal value, for example:
decimal x = 123.45m;
Console.WriteLine(x.ToString()); // Might be 123,45
Console.WriteLine(x.ToString(CultureInfo.InvariantCulture)); // Always 123.45
If you run the above code in (say) France, the default culture will be French, which uses a comma as a decimal separator - so it will print out "123,45".
The rule of thumb to remember is that the invariant culture is suitable for machine-to-machine communications (e.g. formatting values in JSON or XML) whereas other cultures are more suitable for displaying information directly to users.
Although the default culture is originally based on the operating system settings, it can be changed using Thread.CurrentCulture and Thread.CurrentUICulture; the latter is used for looking up translated resources, whereas the former is used for formatting decisions like the above. You can set these properties on any thread, but typically you'd use Thread.CurrentThread.CurrentCulture = ...
No, they are not the same.
The first will take the regional settings from the computer or the culture settings from the application thread running.
The second one will take the English language, according to MSDN:
The invariant culture is culture-insensitive; it is associated with the English language but not with any country/region.
I am working on a .net 4.5 application that needs to be mult lingual supporting multi cultures etc.
The following is sample list of Countries/Languages
Russia / Russian
Belgium / French
Belgium / Dutch
For all the above, there is a CultureInfo object that can be created based upon the above culture names
ru-RU
fr-BE
nl-BE
When the user enters the site, I set Thread.CurrentThread.CurrentCulture and Thread.CurrentThread.CurrentUICulture to the culture created with the above names eg.
Thread.CurrentThread.CurrentCulture = new CultureInfo("nl-BE", false)
Thread.CurrentThread.CurrentUICulture = new CultureInfo("nl-BE", false)
All the above names are valid culture names.
No however I need to added another culture name, language of English in Russia. But the problem is the code en-RU is not valid so when I create new CultureInfo("en-RU", false) I get a CultureNotFoundException as en-RU is not valid.
With this culture, I want the formatting etc of Russia around numbers, dates etc, but I want the language on the site to be English. Is it possbile to create custom CultureInfo objects for invalid culture names with the behaviour of the country (Russia)?
Is it possbile to create custom CultureInfo objects for invalid culture name
Yes.
Make use of CultureAndRegionInfoBuilder to help create the custom CultureInfo. (NB. once you have code to create a culture, the settings to do this can be saved to XML and then loaded, eg. from a resource, which should need less code at runtime.)
An example project how to do that, plus downloadable code, can be found at CodeProject. An important note from the article is that, even though this class sits in the System.Globalization namespace, it is not available by default, quote:
We’ll start by referencing the assembly sysglobl.dll and add a using statement for the namespace System.Globalization.
You may have to mix and mix and match - have a culture object for English which you use for English text but a culture object of ru-Ru (Russian) for numeric formatting.
Or even better create a custom culture combining the two
Create custom culture in ASP.NET
You should use CultureInfo.InvariantCulture Property
The invariant culture is culture-insensitive; it is associated with
the English language but not with any country/region. You specify the
invariant culture by name by using an empty string ("") in the call to
a CultureInfo instantiation method. CultureInfo.InvariantCulture also
retrieves an instance of the invariant culture. It can be used in
almost any method in the System.Globalization namespace that requires
a culture. The objects returned by properties such as CompareInfo,
DateTimeFormat, and NumberFormat also reflect the string comparison
and formatting conventions of the invariant culture.
CultureInfo.InvariantCulture Property
This is other option Custom Global Application Culture
I'm trying to format the date and time on my app based on the users set culture info, however, every help resource I see keeps suggesting that I have to manually enter each culture locale in code. For example, if I wanted en-UK I would have to manually add new CultureInfo("en-UK"); with something like new CultureInfo("en-UK");.
Is there a way to just tap into the currently set culture on the phone without me having to actually type the rtc culture info in? Something that might work like "date = ConvertToLocalCultureFormat(date);"?
I don't know if this works on WinPhone7, but you could use
CultureInfo.CurrentCulture.Name
which return the name of the CurrentCulture of the current thread (en-UK or whatever your app runs in)
See for refs
However this should not be necessary.
If you convert your datetime to a string in this way:
DateTime dt = DateTime.Now;
// Converts dt, formatted using the ShortDatePattern
// and the CurrentThread.CurrentCulture.
string dateInString = dt.ToString("d");
you should get the conversion in the right CultureInfo of your phone.
To format anything using the current culture, you don't have to do anything special at all. The overloads of all formatting that doesn't include a specific format or culture uses the default culture.
The Date.ToString() method for example will call the overload with this.ToString(CultureInfo.CurrentCulture) to pick up the current culture setting of the application and use for the formatting.
Which help resources did you read that suggest you have to manually specify the current culture?
The DateTime.ToString() parameterless method automatically uses formatting information derived from the current culture.
This method uses formatting information derived from the current culture. In particular, it combines the custom format strings returned by the ShortDatePattern and LongTimePattern properties of the DateTimeFormatInfo object returned by the Thread.CurrentThread.CurrentCulture.DateTimeFormat property.
DateTime exampleDate = new DateTime(2008, 5, 1, 18, 32, 6);
string s = exampleDate.ToString();
// Gives "5/1/2008 6:32:06 PM" when the current culture is en-US.
// Gives "01/05/2008 18:32:06" when the current culture is fr-FR.
// Gives "2008/05/01 18:32:06" when the current culture is ja-JP.
I'm building an application that is for a non-profit in Guatemala. Everything in the system is in Quetzales, which is denoted with a Q (i.e. Q100.00) is 100 Quetzales.
I need to be able to modify the monetary values in any DataGridView column, but I've been unable to figure out an easy way to do it with formatting like you can with a dollar sign. I don't want to use computer region settings because some people using the system, use computers from the US.
Not sure if it's important, but values come out of a sql server database from a 'money' type field.
When formatting a string you can specify which culture you want to use:
decimal cost = 1500m;
string s = cost.ToString("C", CultureInfo.GetCultureInfo("es-GT"));
Result
Q1,500.00
If you do not want to rely on the Regional settings you can force the application to execute using the Guatamala culture regardless of the regional settings.
CultureInfo culture = new CultureInfo("es-GT");
decimal amount = 123.43M;
// Set the culture for the thread
System.Threading.Thread.CurrentThread.CurrentCulture = culture;
// Uses the thread culture for formatting
MessageBox.Show(amount.ToString("c"));
// Alternatively if you do not want to set the thread culture
// you can explicitly format using the passed culture
MessageBox.Show(amount.ToString("c", culture));