Format Currency string in c# without currency code - c#

I am trying to format a double to currency string in c#
normally, I would use the following code:
using System;
using System.Globalization;
class Demo {
static void Main() {
double value = 234.66;
Console.WriteLine(value.ToString("C", CultureInfo.InvariantCulture));
Console.WriteLine(value.ToString("C3", CultureInfo.CurrentCulture));
}
}
issue:
The first format prepends an unwanted special caracter: ¤234.66
the later one pepends a dollar sign: $234.660
for normal usecases, I could use several culture infos such as in C# formatting currency given currency code (like USD / GBP / FRF)
unfortunately, Crypto currencies are not supported as far as I know of. So I either look for no currency symbol at all (adding it later to the string) or for a custom currency symbol.
What was quite close was to use balance.ToString("0.##") but in case of 104.10 it would make 104.1 out of it..

var clone = (CultureInfo)CultureInfo.InvariantCulture.Clone();
clone.NumberFormat.CurrencySymbol = "";
var currency = 104.67m;
var stringCurrency = currency.ToString("C", clone);

Related

Strange output when converting string to double

I already searched for my problem but I wasn't successfully and that's the reason I'm here.
All I want to do is reading a string like "3.14" and convert it to double.
Enough said... here is my code:
using System;
namespace GlazerCalcApplication
{
class MainClass
{
public static void Main (string[] args)
{
string heightString;
double height;
heightString = Console.ReadLine();
height = Convert.ToDouble(heightString);
Console.WriteLine(height);
}
}
}
Output:
3.14
314
Press any key to continue...
Why is my double value not 3.14?
Instead of Convert.ToDouble() I also tried it with double.Parse() but I received the same behaviour. Reading strings like 3,14 is no problem.
Maybe I should also mention that I use MonoDevelop and a linux OS.
Thanks in advance.
Try specifying the culture as Invariant:
height = Convert.ToDouble(heightString,CultureInfo.InvariantCulture);
It seems the decimal seperator of your culture is comma instead of dot therefore dot is truncated after conversion.
Convert.ToDouble(string) uses Double.Parse(string, CultureInfo.CurrentCulture) method explicitly.
Here how it's implemented;
public static double ToDouble(String value) {
if (value == null)
return 0;
return Double.Parse(value, CultureInfo.CurrentCulture);
}
It is likely your CurrentCulture's NumberFormatInfo.NumberDecimalSeparator property is not . (dot). That's why you can't parse a string with . as a date seperator.
Example in LINQPad;
CultureInfo c = new CultureInfo("de-DE");
c.NumberFormat.NumberDecimalSeparator.Dump(); // Prints ,
As a solution, you can create a new reference of your CurrentCulture and assing it's NumberDecimalSeparator property to . like;
double height;
CultureInfo c = new CultureInfo("de-DE");
c.NumberFormat.NumberDecimalSeparator = ".";
height = Convert.ToDouble("3.14", c);
Judging by the result I take it you are in a culture zone where comma is the normal decimal separator.
Also, I take it that you want both dot and comma to be used for decimal separation.
If not, the below is not the proper solution.
The fastest solution for using both would be
height = Convert.ToDouble(heightString.Replace('.', ',');
This would mean that both dots and comma's are used as comma and thus parsed as a decimal separator.
If you only want to use a dot as separator, you can use invariantculture or a specific numberformatinfo. Invariant culture is already shown in the other posts. numberformat info example:
var nfi = new NumberFormatInfo { NumberDecimalSeparator = "." };
height = double.Parse(heightString,nfi);
For completeness, the example below shows both using numberformatinfo for setting the dot as decimal separator, as well as replacing comma with dots, so both characters are used for decimals
var nfi = new NumberFormatInfo { NumberDecimalSeparator = "." };
height = double.Parse(heightString.Replace(',', '.'),nfi);
Different .Net cultures (countries) have different decimal separators.
If you expect input values to be in some specific format - either use some particular culture or InvariantCulture. Also consider using double.Parse as it geve more flexibility on parsing the values than generic Convert.ToDouble.
var d = double.Parse(heightString, CultureInfo.InvariantCulture);
If you expect user to enter value in local format - your code is fine, but either your expectation of "local format" is wrong, or "current culture" set incorrectly.

How to convert decimal to money format

I'm trying to convert a number so it looks like the formatting in money.
I need to take 258000 and make it 2,580.00 or 25000 and make it 250.00 or 360 and make it 3.60
This is what I'm using but it's adding the ".00" at the end of all numbers making 2500 2500.00 but it should be 25.00.
Value = string.Format("{0:##,###.00}", Convert.ToDecimal(Value));
It seems to me that you're just missing the fact that you can divide the user's input by 100 after parsing it:
using System;
class Program
{
static void Main(string[] args)
{
string input = "2500";
decimal cents = decimal.Parse(input); // Potentially use TryParse...
decimal dollars = cents / 100m;
string output = dollars.ToString("0.00");
Console.WriteLine(output); // 25.00
}
}
Note that there are complicated cultural rules around how currency values should be displayed - I would suggest using the C format specifier, using a CultureInfo which is like whatever the users are expecting, but with the NumberFormatInfo.CurrencySymbol set to an empty string.
You should also consider which culture to use when parsing the user's input - it can significantly affect the results if they decide to use grouping separators or decimal separators. Will they always be entering an integer? If so, parse it as an integer too.
double valueOriginal = 260;
Response.Write( (valueOriginal / 100).ToString("C"));
260 = (206/100)
then
(260/100).ToString("C");

How do I handle countries that use multiple currencies in .NET?

I have an application where I want to format a currency using the country's native currency formatting. Problem is, certain countries use multiple currencies, but .NET only assigns one currency per country. For example, Romania uses EUR and RON. When I get the currency info from .NET:
var cultureInfo = new CultureInfo("ro-RO");
Console.WriteLine("cultureInfo.NumberFormat.CurrencySymbol);
The output is leu, which is the RON currency type.
How would I get EUR for this case in .NET? I have the 3-letter ISO currency code (EUR) and the country language (ro-RO) but I don't know how to use this info to get a correctly-formatted euros currency string.
You can replace currency symbol with a custom one (leu to euro in this case)
NumberFormatInfo LocalFormat = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone();
LocalFormat.CurrencySymbol = "€";
decimal money = 100;
Console.WriteLine(money.ToString("c", LocalFormat));
I thought I'd give you a static helper class answer like following:
static class CurrencySymbolHelper
{
public static string GetCurrencySymbol(CultureInfo cultureInfo, bool getAlternate)
{
if (cultureInfo.Name == "ro-RO" && getAlternate)
return "EUR";
return cultureInfo.NumberFormat.CurrencySymbol;
}
}
You can pass what ever variable you want into the method and do any operations within it you wish. Call as following:
var cultureInfo = new CultureInfo("ro-RO");
Console.WriteLine(CurrencySymbolHelper.GetCurrencySymbol(cultureInfo,false));
Issue is, you have to call this helper when ever you want to get currency info instead of cultureInfo.NumberFormat.CurrencySymbol

C#: Extract number out of string, then change comma(,) to dot(.)

I'm using Visual Web Ripper to extract name and prices on products on a website.
When i extract the price from a table it comes in a form like this:
Kr. 129,30
I need to extract the 129,30, then turn the comma to a dot (129.30).
Visual Web Ripper can use scripts to modify the extracted content. It can use standard Regex, C# and VB.NET.
In the Regex tab I have found that
(\d+.)?(\d+)(.\d+)?
gives me 129,30, but then I can't change the comma into a dot.
Therefor I have to use C#. It comes with this standard script:
using System;
using VisualWebRipper.Internal.SimpleHtmlParser;
using VisualWebRipper;
public class Script
{
//See help for a definition of WrContentTransformationArguments.
public static string TransformContent(WrContentTransformationArguments args)
{
try
{
//Place your transformation code here.
//This example just returns the input data
return args.Content;
}
catch(Exception exp)
{
//Place error handling here
args.WriteDebug("Custom script error: " + exp.Message);
return "Custom script error";
}
}
}
How do I modify it to extract the number then replace the comma with a dot?
This is obviously Krona, so we should use the Swedish culture info to translate it. First we start with the input:
var original = "Kr. 129,30";
Get the culture:
using System.Globalization;
var culture = CultureInfo.GetCultureInfo("sv-SE");
This culture expects the currency string to be kr (case insensitive) but we have Kr.. So let's update it:
var format = (NumberFormatInfo)culture.NumberFormat.Clone();
format.CurrencySymbol = "Kr.";
And now the culture aware parse:
var number = Decimal.Parse(original, NumberStyles.Currency, format);
Now number contains a decimal that has been parsed correctly.
String.Replace is an option ( text.Replace(",", ".")).
It would be better to properly parse number with correct CultureInfo and than reformat it back with InvariantCulture.

Format a double value like currency but without the currency sign (C#)

I feed a textbox a string value showing me a balance that need to be formatted like this:
###,###,###,##0.00
I could use the value.ToString("c"), but this would put the currency sign in front of it.
Any idea how I would manipulate the string before feeding the textbox to achieve the above formatting?
I tried this, without success:
String.Format("###,###,###,##0.00", currentBalance);
Many Thanks,
If the currency formatting gives you exactly what you want, clone a NumberFormatInfo with and set the CurrencySymbol property to "". You should check that it handles negative numbers in the way that you want as well, of course.
For example:
using System;
using System.Globalization;
class Test
{
static void Main()
{
NumberFormatInfo nfi = CultureInfo.CurrentCulture.NumberFormat;
nfi = (NumberFormatInfo) nfi.Clone();
Console.WriteLine(string.Format(nfi, "{0:c}", 123.45m));
nfi.CurrencySymbol = "";
Console.WriteLine(string.Format(nfi, "{0:c}", 123.45m));
}
}
The other option is to use a custom numeric format string of course - it depends whether you really want to mirror exactly how a currency would look, just without the symbol, or control the exact positioning of digits.
string forDisplay = currentBalance.ToString("N2");
Have you tried:
currentBalance.ToString("#,##0.00");
This is the long-hand equivalent of:
currentBalance.ToString("N2");
string result=string.Format("{0:N2}", value); //For result like ### ### ##.##
You can do this with the group separator and the section separator, like this:
currentBalance.ToString("#,0.00;(#,0.00)");
This does not account for culture variances like the answer from #JonSkeet would, but this does mimic decimal place, rounding, thousands separation, and negative number handling that en-US culture currency format produces using a single custom format string.
.NET Fiddle Demo
var result = currentBalance.ToString("C").Replace(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.CurrencySymbol, "");
CultureInfo cultureInfo = new CultureInfo("en-US");
cultureInfo.NumberFormat.CurrencySymbol = "Rs.";
Thread.CurrentThread.CurrentCulture = cultureInfo;
decimal devimalValue = 3.45M;
this.Text = devimalValue.ToString("C2"); //Rs.3.45
This may be overkill, but it rounds, formats...
#helper TwoDecimalPlaces(decimal? val)
{
decimal x = 0;
decimal y = 0;
string clas = "text-danger";
if (val.HasValue)
{
x = (decimal)val;
if (val > 0)
{
clas = "";
}
}
y = System.Math.Round(x, 2);
IFormatProvider formatProvider = new System.Globalization.CultureInfo(string.Empty);
<span class="#clas">#string.Format("{0:N2}", y)</span>
}
This simple solution works for me with US currency.
If not needing international currency support use this and replace the $ with the currency symbol(s) to be removed:
// for USD
string result = currentBalance.ToString("C").Replace("$", "")
or
// for EUR
string result = currentBalance.ToString("C").Replace("€", "")

Categories