String.Format("{0:C2}", -1234) (Currency format) treats negative numbers as positive
Asked Answered
H

4

21

I am using String.Format("{0:C2}", -1234) to format numbers.

It always formats the amount to a positive number, while I want it to become $ - 1234

Hesperian answered 16/6, 2009 at 12:18 Comment(0)
H
10

I think I will simply use:

FormatCurrency(-1234.56, 2, UseParensForNegativeNumbers:=TriState.False)

(in Microsoft.VisualBasic.Strings module)

Or in shorter words (this is what im actually going to use):

FormatCurrency(-1234.56, 2, 0, 0)

Or I will make myself a custom formatcurrency function that uses the VB function passing my custom params.

For further details take a look at the FormatCurrency Function (Visual Basic) in the msdn.

Hesperian answered 16/6, 2009 at 12:43 Comment(0)
Y
33

Am I right in saying it's putting it in brackets, i.e. it's formatting it as ($1,234.00) ? If so, I believe that's the intended behaviour for the US.

However, you can create your own NumberFormatInfo which doesn't behave this way. Take an existing NumberFormatInfo which is "mostly right", call Clone() to make a mutable copy, and then set the CurrencyNegativePattern appropriately (I think you want value 2).

For example:

using System;
using System.Globalization;

class Test
{
    static void Main()
    {
        var usCulture = CultureInfo.CreateSpecificCulture("en-US");
        var clonedNumbers = (NumberFormatInfo) usCulture.NumberFormat.Clone();
        clonedNumbers.CurrencyNegativePattern = 2;
        string formatted = string.Format(clonedNumbers, "{0:C2}", -1234);
        Console.WriteLine(formatted);
    }
}

This prints $-1,234.00. If you actually want exactly $-1234, you'll need to set the CurrencyGroupSizes property to new int[]{0} and use "{0:C0}" instead of "{0:C2}" as the format string.

EDIT: Here's a helper method you can use which basically does the same thing:

private static readonly NumberFormatInfo CurrencyFormat = CreateCurrencyFormat();

private static NumberFormatInfo CreateCurrencyFormat()
{
    var usCulture = CultureInfo.CreateSpecificCulture("en-US");
    var clonedNumbers = (NumberFormatInfo) usCulture.NumberFormat.Clone();
    clonedNumbers.CurrencyNegativePattern = 2;
    return clonedNumbers;
}

public static string FormatCurrency(decimal value)
{
    return value.ToString("C2", CurrencyFormat);
}
Yammer answered 16/6, 2009 at 12:24 Comment(8)
Excellent catch. I ran a quick string.Format('{0:C2}', -1234) in boo, got '-$1,234.00' and thought Shimmy was somehow mistaken (sorry Shimmy). I didn't realize that Canada and the US differed on NumberFormat.CurrencyNegativePattern.Presber
I want to do everything in one line. Also I wanna get a result format decimal negatives with 2 leading zeros (i.e. $-1234.56)Hesperian
If you want to do everything in one call, you'll need to put this in a helper method somewhere. I don't see how you've shown 2 leading zeros in "$-1234.56". You might want to update your question to show what you actually want (as you don't want $-1234, contrary to the question).Yammer
BTW, yes, it's putting in brackets, that's weird.Hesperian
It's not particularly weird - that's how negative values are represented in various accounting systems.Yammer
Absolutely. (That's why it's part of NumberFormatInfo.)Yammer
How would you do use a custom NumberFormatInfo class in XAML with StringFormat inside a binding expression? I can create a local resource and set the NegativePattern property, but then what?Kobold
In what country's culture negative money values are represented as positive? I want to live there!Roana
T
24

Another simple option is manually specify the format string.

String.Format("{0:$#,##0.00}", -1234)

Or, if the currency symbol needs to be a parameter, you could do this

String.Format("{0:" + symbol + "#,##0.00}", -1234)
Triptolemus answered 21/6, 2011 at 15:56 Comment(3)
This is a great answer. Thank you! How about "{0:$#,0.00}"? It seems to do the same for me, and I wonder what cases I am missing.Fonda
Microsoft: Simple things made complex.Roana
Can anybody explain the magic behind this code String.Format("{0:$#,##0.00}", -1234)? or where can I learn more about it?Gunfire
H
10

I think I will simply use:

FormatCurrency(-1234.56, 2, UseParensForNegativeNumbers:=TriState.False)

(in Microsoft.VisualBasic.Strings module)

Or in shorter words (this is what im actually going to use):

FormatCurrency(-1234.56, 2, 0, 0)

Or I will make myself a custom formatcurrency function that uses the VB function passing my custom params.

For further details take a look at the FormatCurrency Function (Visual Basic) in the msdn.

Hesperian answered 16/6, 2009 at 12:43 Comment(0)
D
0
#region Format value to currency
    /// <summary>
    /// Method to format input in currency format
    ///  Input:  -12345.55
    ///  Output:$-12,345.55  
    /// </summary>
    /// <param name="Input"></param>
    /// <returns></returns>
    public static string FormatToCurrency(string Input)
    {
        try
        {
            decimal value = Convert.ToDecimal(Input);
            CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
            culture.NumberFormat.NumberNegativePattern = 2;
            return string.Format(culture, "{0:C}", value);
        }
        catch (Exception)
        {
            return string.Empty;
        }
    }
    #endregion
Dreher answered 21/5, 2020 at 20:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.