How does a values with decimal separators work with ToString with CultureInfo.InvariantCulture setting for Non english locale

754 Views Asked by At

I have a simple use case where I am using a system with German language set as system locale (regional format as German as well as current system locale as German).

e.g.

string sourceValue = "0,123";
string target_invariant = sourceValue.ToString(CultureInfo.InvariantCulture);
string targetValue = sourceValue.ToString();

Console.WriteLine(target_invariant); // shows 0,123
Console.WriteLine(targetValue); // 0,123

I would have expected that using InvariantCulture with ToString would produce a culture neutral format such as "0.123" which it does not!!

3

There are 3 best solutions below

0
Prasad Telkikar On

Instead of converting string into another string with InvariantCulture won't help you to convert decimal value with .,

You need to parse given sourceValue to decimal with german culture,

//You can parse as double too.
decimal result = decimal.Parse(sourceValue, CultureInfo.GetCultureInfo("de-de"));

Now you can print with . using CultureInfo.InvariantCulture,

Console.WriteLine(result.ToString(CultureInfo.InvariantCulture));

Try online : .Net Fiddle

0
Caius Jard On

Not quite sure why Prasad deleted their answer - it looked close to being a solution for you, just was using the wrong culture for parsing..

Anyways, parse your number using its culture and then print the result of turning the number to a string with different cultures

var germanCulture = System.Globalization.CultureInfo.GetCultureInfo("de-de");
     
decimal sourceValue = decimal.Parse("0,123", germanCulture);
string target_invariant = sourceValue.ToString(System.Globalization.CultureInfo.InvariantCulture);
string targetValue = sourceValue.ToString(germanCulture);
Console.WriteLine(target_invariant);
Console.WriteLine(targetValue);     

Credit for most of this code goes to sir rufo's fiddle, it just didn't have the parsing step in, which seemed rather vital to your overall mission

0
sommmen On

Let's take a look at the implementation of String.ToString():

// Returns this string.
public override string ToString()
{
    return this;
}

// Returns this string.
public string ToString(IFormatProvider? provider)
{
    return this;
}

As you can see just the same instance gets returned. This is also reflected in the documentation, which will show up in intellisense (but i'm unsure whether that is from visual studio of the resharper plugin):

enter image description here

What you should do is parse the string to an floating point data type and then convert that to the appropriate culture.

string sourceValue = "0,123";
var sourceInt = double.Parse(sourceValue, CultureInfo.InvariantCulture);

string target_invariant = sourceValue;
string targetValue = sourceInt.ToString(CultureInfo.CurrentUICulture);

This will use double.ToString(...) which actually uses the culture:

public string ToString(IFormatProvider? provider)
{
    return Number.FormatDouble(m_value, null, NumberFormatInfo.GetInstance(provider));
}