50

I have a string read from a textbox. It contains a comma for decimal separation.

I have NumberFormatInfo.CurrencyDecimalSeparator set to , (comma) but when I convert the string to decimal Convert.ToDecimal(mystring); I obtain a dot separate value for decimal.

Example:

decimal a=Convert.ToDecimal("1,2345"); ----> decimal is 1.2345

I have tried also:

double a=Convert.ToDouble("1,2345"); 

but dot for decimal again

damienfrancois
  • 52,978
  • 9
  • 96
  • 110
LoveMyWife
  • 633
  • 1
  • 5
  • 8

9 Answers9

60

All this is about cultures. If you have any other culture than "US English" (and also as good manners of development), you should use something like this:

var d = Convert.ToDecimal("1.2345", new CultureInfo("en-US"));
// (or 1,2345 with your local culture, for instance)

(obviously, you should replace the "en-US" with the culture of your number local culture)

the same way, if you want to do ToString()

d.ToString(new CultureInfo("en-US"));
radbyx
  • 9,352
  • 21
  • 84
  • 127
Agat
  • 4,577
  • 2
  • 34
  • 62
  • Hi Guys, Thanks for reply I have tried decimal d = Convert.ToDecimal("1,2345", new CultureInfo("it-IT")); but don't work I'm viewing the value from visual studio Debug (local variable contain 1**.**2345) and I print this in a xml file and I obtain this node 1**.**2345 I have NumberFormatInfo.CurrencyDecimalSeparator set to , (comma). I view it from runtime in a debug mode. I hope this help you to undertand, and me too :) Bye – LoveMyWife Nov 10 '13 at 19:47
  • Are you sure you are actually locating the problem correctly? If you write something to xml file (and read it) -- you should ask about "howto(s)" xml-related ones, as Convert.ToDecimal and ToString() methods are some absolutely unrelated things to how exactly you are working with xml (-reader/-writer or any other way you manage the xml file). In that case, you should create a new question which actually describes and show the part with your code work logic with xml file. – Agat Nov 10 '13 at 19:52
  • 1
    `CultureInfo.InvariantCulture` might be a better choice. See a [DotnetFiddle](https://dotnetfiddle.net/uCGVy0) for examples. – LosManos Aug 26 '16 at 08:52
  • It all depends. The "en-US" value was used just for example. As if you are developing context (culture) dependent application, it might be used some other culture like "uk-UA", where coma is used by default. However, CultureInfo.InvariantCulture won't work in that case as it's culture independent. – Agat Aug 26 '16 at 18:37
  • 2
    If you do a lot of parsing, consider using `CultureInfo.GetCultureInfo("en-US")` instead of `new CultureInfo("en-US")`. That is because the former returns the same cached instance over and over again, while the latter clearly has to create a new object every time (one that the garbage collector will soon remove again). However, the two are not entirely equivalent wrt. the `UseUserOverride` property of the culture object. So consider what you want to happen if the user has changed the settings for `en-US` in the operating system. – Jeppe Stig Nielsen Sep 01 '19 at 22:01
41

Instead of replace we can force culture like

var x = decimal.Parse("18,285", new NumberFormatInfo() { NumberDecimalSeparator = "," });

it will give output 18.285

Antonio Bakula
  • 20,445
  • 6
  • 75
  • 102
Ashok Mandial
  • 545
  • 3
  • 5
10

Thanks for all reply.

Because I have to write a decimal number in a xml file I have find out the problem. In this discussion I have learned that xml file standard use dot for decimal value and this is culture independent. So my solution is write dot decimal number in a xml file and convert the readed string from the same xml file mystring.Replace(".", ","); Thanks Agat for suggestion to research the problem in xml context and Ε Г И І И О because I didn't know visual studio doesn't respect the culture settings I have in my code.

Community
  • 1
  • 1
LoveMyWife
  • 633
  • 1
  • 5
  • 8
  • 1
    That's not "VisualStudio" settings, but your .NET framework configuration (which is dependent on your Windows configuration). (This can be also web server settings). Those can be configured via app.config, web.config. – Agat Nov 30 '13 at 17:04
  • And using '.Replace(' is not really correct approach, as on another system it might be broken vise versa (if standard system settings are "en-US"). – Agat Nov 30 '13 at 17:05
4

I ended up using this solution.

decimal weeklyWage;
decimal.TryParse(items[2],NumberStyles.Any, new NumberFormatInfo() { NumberDecimalSeparator = "."}, out weeklyWage);
Gervo
  • 73
  • 1
  • 7
2

You are viewing your decimal or double values in Visual Studio. That doesn't respect the culture settings you have on your code.

Change the Region and Language settings on your Control Panel if you want to see decimal and double values having the comma as the decimal separator.

Ε Г И І И О
  • 11,199
  • 1
  • 48
  • 63
0

I had faced the similar issue while using Convert.ToSingle(my_value) If the OS language settings is English 2.5 (example) will be taken as 2.5 If the OS language is German, 2.5 will be treated as 2,5 which is 25 I used the invariantculture IFormat provided and it works. It always treats '.' as '.' instead of ',' irrespective of the system language.

float var = Convert.ToSingle(my_value, System.Globalization.CultureInfo.InvariantCulture);

  • you can also use the IFormat provider for parsing *.Parse(my_value, System.Globalization.CultureInfo.InvariantCulture); – Varma Naidu V Mar 13 '19 at 11:55
0
double prc;

Console.WriteLine(prc.ToString("F2") + "  :  " + prc.ToString("F2").Replace(",", "."));
Adriaan
  • 17,741
  • 7
  • 42
  • 75
Mttzern
  • 1
  • 1
  • 4
    Welcome to Stack Overflow! Please read [answer] and [edit] your question to contain an explanation as to why this code would actually solve the problem at hand. Always remember that you're not only solving the problem, but are also educating the OP and any future readers of this post. – Adriaan Jul 22 '22 at 12:10
0

Define this extend of string in any c# file:

public static class ExtendString
{
    /// <summary>
    /// Transform a string into decimal (else return null if not possible)
    /// </summary>
    public static decimal? ParseToDecimal(this string str)
    {
        if (str.IsNullOrEmpty()) return null;
        if (decimal.TryParse(str, NumberStyles.Any, CultureInfo.CurrentUICulture, out decimal d))
            return d;
        if (decimal.TryParse(str, System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out d))
            return d;
        return null;
    }
}

Then anywhere in your source code you can do this without having to think about "how to format your string before parsing it":

decimal? res = "12.54".ParseToDecimal(); // <-- returns a valid decimal
res = "12,54".ParseToDecimal(); // <-- returns a valid decimal
res = "notADecimal".ParseToDecimal(); // <-- returns null
Quentin CG
  • 748
  • 5
  • 6
-1
    usCulture = new CultureInfo("vi-VN");
Thread.CurrentThread.CurrentCulture = usCulture;
Thread.CurrentThread.CurrentUICulture = usCulture;
usCulture = Thread.CurrentThread.CurrentCulture;
dbNumberFormat = usCulture.NumberFormat;
number = decimal.Parse("1.332,23", dbNumberFormat); //123.456.789,00

usCulture = new CultureInfo("en-GB");
Thread.CurrentThread.CurrentCulture = usCulture;
Thread.CurrentThread.CurrentUICulture = usCulture;
usCulture = Thread.CurrentThread.CurrentCulture;
dbNumberFormat = usCulture.NumberFormat;
number = decimal.Parse("1,332.23", dbNumberFormat); //123.456.789,00

/*Decision*/
var usCulture = Thread.CurrentThread.CurrentCulture;
var dbNumberFormat = usCulture.NumberFormat;
decimal number;
decimal.TryParse("1,332.23", dbNumberFormat, out number); //123.456.789,00