Currency formatting in .NET gives white space between amount and currency
Asked Answered
F

7

6

I'm having issues with currency formatting in C#. I'm using framework 2.0.

When I use this code:

CultureInfo culture = new CultureInfo("fr-FR", false);
NumberFormatInfo numberFormatInfo = (NumberFormatInfo)culture.NumberFormat.Clone();
numberFormatInfo.CurrencySymbol = "CHF";

price.Value.ToString("C", numberFormatInfo) seems to give me a string with a white space between amount and currency. That's horrible! I absolutely need a no-break space! What is going on? Am I missing a format property or is it the C# standard?

Thanks for your help!

So basically you want price.Value.ToString("C", numberFormatInfo).Replace(' ', '\u00A0');? At least that should be the code for non breaking space. – Corak

Exactly the same as above commentor, but using the asci-values instead; > price.Value.ToString("C", numberFormatInfo).Replace((char) 32, (char) 160); (160 is a lot > easier to remember, atleast for me :)) – flindeberg

Felty answered 11/9, 2013 at 14:12 Comment(6)
Seems as though we're missing some relevant codeMoan
So basically you want price.Value.ToString("C", numberFormatInfo).Replace(' ', '\u00A0');? At least that should be the code for non breaking space.Nuristan
Exactly the same as above commentor, but using the asci-values instead; price.Value.ToString("C", numberFormatInfo).Replace((char) 32, (char) 160); (160 is a lot easier to remember, atleast for me :))Shumpert
Yeah that seems correct. I'm so tired that I missed that. Nice one, I guess it fits perfectly!Felty
@Shumpert - isn't that just for codepage 1252? I'd use the unicode notation, just to be sure. ^_^;Nuristan
@Corak, well, yeah, but for more codepages than just 1252, hasn't failed me yet though, so untill that day I will blindly go by (char) 160 :)Shumpert
S
8

Adding an answer based on my interpretation of the question, which @Corak seems to share.

// Convert "breaking" spaces into "non-breaking" spaces (ie the html  )
price.Value.ToString("C", numberFormatInfo).Replace((char) 32, (char) 160);

Doing the same with unicode (courtesy of @Corak's link):

// Convert "breaking" spaces into "non-breaking" spaces without int cast to char
price.Value.ToString("C", numberFormatInfo).Replace(' ', '\u00A0');

And btw (roslyn repl):

> '\u00A0' == (char) 160
true

And if you are going to be using it alot also get the extension method:

public static class StringExtensions 
{// CurrencyType is your currency type, guessing double or decimal?
 public static string ToCurrencyString(this CurrencyType value, IFormatInfo format)
 {
    return value.ToString("C", format).Replace((char) 32, (char) 160);
 }
}
Shumpert answered 11/9, 2013 at 15:23 Comment(0)
O
7

Use:

numberFormatInfo.CurrencyPositivePattern = 1;

For value 1 the format is n$ where $ is currency symbol and in your case its CHF

Formatting Types - MSDN

The CurrencyNegativePattern or CurrencyPositivePattern property, which returns an integer that determines the following:

  • The placement of the currency symbol.
  • Whether negative values are indicated by a leading negative sign, a trailing negative sign, or parentheses.
  • Whether a space appears between the numeric value and the currency symbol.

Try the following code:

    CultureInfo culture = new CultureInfo("fr-FR", false);
    NumberFormatInfo numberFormatInfo = (NumberFormatInfo)culture.NumberFormat.Clone();
    numberFormatInfo.CurrencySymbol = "CHF";
    numberFormatInfo.CurrencyPositivePattern = 1;
    decimal d = 123.23M;
    var temp = d.ToString("C", numberFormatInfo);

Output:

123,23CHF
Ossetic answered 11/9, 2013 at 14:22 Comment(10)
Thanks for your reply! Interesting stuff in here it quite solves my problem. The thing is I don't want neither a space, neither no space, I need a no-break space which sticks the amount and the currency together no matter what. It seems that negative pattern 14 and 15 would be what i'm looking for. But... if I need to specify the way currency is displayed (left or right), what's the point of using culture? Besides, the positive pattern has no such thing, which is weird.Felty
What do you mean by No-Break space, its either space or no space.Ossetic
It's a space which does not allow to break the line between two words. Its equivalent in HTML would be   (No Break SPace) And by the way, I think it's the norm. Why would you like the amount and currency separately? That's why I find weird that it's not natively implemented.Felty
@user1835565, I am not sure how you are displaying it. but the result would be a string in C#, and there is no concept of no break space as far as I know in C#. Probably there are settings that are letting you display the string differently.Ossetic
A bonus question is : how to give a no-break space in a response? I have tried several codes such as "\u00A0" but the source shows a classic space. In C#, of course, it doesn't mean anything. But still, the char   exists in C#. Several identical no-break chars exist. I'm thinking of creating my own money Object to manage this, but I just don't know how to use them.Felty
@Ossetic - see non breaking space. It basically looks like a space, but does not signify that one word ends and the other one starts. Mostly used to not "break" two words at the end of a line.Nuristan
@Felty - "several identical"? C# char is unicode and the only unicode definition for non breaking space as far as I see is U+00A0. - "source shows a classic space", does it just look like a classic space or does it also behave like one (i.e. breaks)? Maybe the displaying side does not know about or does not have non breaking spaces and therefore maps it to a classic space.Nuristan
@Corak, thanks for the info, so having a non breaking space in string would prevent it breaking down multiple lines ?Ossetic
@Ossetic - Let's use a TeX example. "This is~a string". the ~ is the nbsp. This string could be broken into "This", "is~a" and "string". But "is" and "a" will not be broken up, no matter what. - For the output, the ~ would be invisible. So it would just look like "This is a string"Nuristan
@Corak, ah beautiful. Thanks for the info. Learned something new. Thanks againOssetic
K
5

You can replace it.

price.ToString("C", numberFormatInfo).Replace(" ", "")

or better set NumberFormatInfo.CurrencyPositivePattern to 1

numberFormatInfo.CurrencySymbol = "CHF";
numberFormatInfo.CurrencyPositivePattern = 1;

Full example;

CultureInfo culture = new CultureInfo("fr-FR", false);
NumberFormatInfo numberFormatInfo = (NumberFormatInfo)culture.NumberFormat.Clone();
numberFormatInfo.CurrencySymbol = "CHF";
numberFormatInfo.CurrencyPositivePattern = 1;
Console.WriteLine((1.5M).ToString("C", numberFormatInfo));

Output will be;

1,50CHF

Here a DEMO.

From Formatting Types

The CurrencyNegativePattern or CurrencyPositivePattern property, which returns an integer that determines the following:

  • The placement of the currency symbol.

  • Whether negative values are indicated by a leading negative sign, a trailing negative sign, or parentheses.

  • Whether a space appears between the numeric value and the currency symbol.

Kirkendall answered 11/9, 2013 at 14:16 Comment(0)
E
3

You can configure the CurrencyPositivePattern and set it to something appropriate.

// whatever code you had
NumberFormatInfo numberFormatInfo = (NumberFormatInfo)culture.NumberFormat.Clone();
numberFormatInfo.CurrencyPositivePattern = 1; // will format like 25.00CHF
Elrod answered 11/9, 2013 at 14:18 Comment(0)
A
1

Seems like by default it includes space when it comes to other currencies than $

double value = 12345.6789;
Console.WriteLine(value.ToString("C", CultureInfo.CurrentCulture));

Console.WriteLine(value.ToString("C3", CultureInfo.CurrentCulture));

Console.WriteLine(value.ToString("C3", 
                  CultureInfo.CreateSpecificCulture("da-DK")));
// The example displays the following output on a system whose 
// current culture is English (United States): 
//       $12,345.68 
//       $12,345.679 
//       kr 12.345,679

if you want to replace space, you can use as Soner said,

numberString.ToString("C", numberFormatInfo).Replace(" ", "");
Afloat answered 11/9, 2013 at 14:18 Comment(0)
Z
0

In your global.asax ou can globaly change the culture and chose to remove the space like this :

CultureInfo cultureInfo = CultureInfo.CreateSpecificCulture("fr-FR"); //Get you own culture
cultureInfo.NumberFormat.CurrencyPositivePattern = 1; //To remove the space
Thread.CurrentThread.CurrentUICulture = cultureInfo; //Apply globaly to your application
Thread.CurrentThread.CurrentCulture = cultureInfo; //Apply globaly to your application
Zamia answered 15/2, 2019 at 8:43 Comment(0)
C
0

The clean solution is set your CurrencyPositivePattern to 0. Example:

CultureInfo _culture= (CultureInfo) culture.Clone();
_culture.NumberFormat.CurrencyPositivePattern = 0;
var stringFormat = number.ToString("c3", _culture);

input: 1234567.845
output: $1.234.568
output: €1.234.568
output: S/1.234.568

Coed answered 25/3, 2022 at 16:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.