Why does String.Format converts minus to parenthesis

Viewed 62

I am using String.Format to add $ sign into values.

 var result = string.Format("{0:C}", Convert.ToDecimal(amount));

when amount is negative it converts minus sign into parenthesis- like below

-11.00 --> ($11.00)

I need this

-11.00 --> -$11.00

How can I fix this ?

3 Answers

Parentheses is the preferred accounting format to display negative currency, in the US at least. See this UX.SE post.

If you don't want to follow that convention, you can create your own NumberFormatInfo:

var format = CultureInfo.CreateSpecificCulture("en-US").NumberFormat;

// "1" means "-$n"
format.CurrencyNegativePattern = 1;

string.Format(format, "{0:C}", -1m) // "-$1.00"

See this for a list of the values that you can put in CurrencyNegativePattern.

You actually have a lot of control over how your numbers are output, if you don't want to use the standard cultures. In fact you can make up you're own currency symbols if you want.

Here's how you can customize the decimal.ToString output:

var money = -4.21345m;

var ni = new System.Globalization.NumberFormatInfo()
{
    CurrencySymbol = "₿",
    CurrencyDecimalDigits = 5,
};

for (var i = 0; i < 16; i++)
{
    ni.CurrencyNegativePattern = i;
    Console.WriteLine(money.ToString("C", ni));
}

That gives me:

(₿4.21345)
-₿4.21345
₿-4.21345
₿4.21345-
(4.21345₿)
-4.21345₿
4.21345-₿
4.21345₿-
-4.21345 ₿
-₿ 4.21345
4.21345 ₿-
₿ 4.21345-
₿ -4.21345
4.21345- ₿
(₿ 4.21345)
(4.21345 ₿)

Sorry to say this, but for the C literal the output ($11.00) is correct. It is a typical bookkeeping format for writing negative numbers. You could change this in your Windows settings, but then the change would be global for the system and probably that's not what you want.

The easy solution would be to use:

var result = string.Format("${0:0.00}", Convert.ToDecimal(amount));

But then the USD sign is hard-coded (by the way that is the more "correct" variant than writing the USD sign after the minus as shown in your last code line). If you want to make it flexible and nevertheless custom, you could get the currency information and the decimal separator from the system culture settings until its fitting your requirements.

Related