CultureInfo in C# - c#

My system is id-ID, using ',' as decimal separator. I have problems with data in en-US, I want to convert it to id-ID and then back to en-US :
List<string> list = new List<string>(){"0.14","223.54"}; // en-US
list[0] = Convert.ToDecimal(list[0], CultureInfo.InvariantCulture).ToString();
MessageBox.Show("list[0] = " + list[0]); //display "0,14", it is ok!
MessageBox.Show("list[1] = " + list[1]); //display "223,54", it is ok!
Now I want to change it back to US culture, I can simply use Replace to change ',' back to '.' as US culture.
MessageBox.Show("list[0] = " + list[0].Replace(",", ".")); //displays "0.14"
But it is not an elegant way to handle it, I wish I can handle it with CultureInfo, so I try the following statements but can't work!
CultureInfo us = new CultureInfo("en-US");
list[0] = Convert.ToDecimal(list[0], us).ToString();
list[1] = Convert.ToDecimal(list[1], us).ToString();
MessageBox.Show("list[0] = " + list[0]); //display "14", the decimal separator is missing!
MessageBox.Show("list[1] = " + list[1]); //display "223,54", nothing changed!

en-US culture uses comma as a number group separator. This a reason of the mistake.
Better approach is to store decimal as decimal. Use required culture when you output data:
List<string> stringList = new List<string>() { "0.14", "223.54" };
List<decimal> list = stringList.Select(Convert.ToDecimal).ToList();
MessageBox.Show(list[0].ToString(CultureInfo.InvariantCulture));
MessageBox.Show(list[0].ToString(new CultureInfo("en-US")));
MessageBox.Show(list[0].ToString(new CultureInfo("id-ID")));

Related

Peso Symbol in C#

if (num1 == 5)
{
Console.WriteLine("\nThe " + num2 + " kilo/s of {0} " + 28 + " per kilo ", "GRAPES");
Console.WriteLine("The total amount is {0}{1}", num2.ToString("en-PHI"),num2*28);
}
num2.ToString("en-PHI")
I try this one but it doesn't work at all .. it just copy the en-PHI..
Sounds like you want to provide the culture en-PHI... although that isn't a valid culture name apparently. Perhaps you just want phi as the language?
var culture = CultureInfo.GetCultureInfo("phi");
var text = string.Format(culture, "The total amount is {0:c}", num2 * 28);
Console.WriteLine(text);
The c format specifier is "currency".
That's the way of printing the currency symbol known for a specific culture... now that might not do exactly what you want, but it's probably a matter of finding the right culture.
If you really just want to hard-code the peso character (U+20B1) you can do that directly:
Console.WriteLine("The total amount is \u20b1{0}", num2);
Now if that prints a "?" it means the current console encoding or font doesn't support the peso symbol. Running this from the command line will set it to UTF-8:
> chcp 65001
Make sure the font you're using supports the character as well.

Office Open XML SDK Spreadsheet how to display currency symbol in front of number?

As you've read in the title, I've been looking for a way to format a spreadsheet cell with currency format. Using the code below I do get my currency format but the currency symbol is displayed after the numbers.
// currency format
stylesheet.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.CellFormats>().InsertAt<DocumentFormat.OpenXml.Spreadsheet.CellFormat>(
new DocumentFormat.OpenXml.Spreadsheet.CellFormat()
{
NumberFormatId = 164,
ApplyNumberFormat = true
},
8);
Does anyone know the NumberFormatId for currency format that display currency symbol in the front?
It turns out I need to add basic style to my spreadsheet. The code below adds basic style for currency.
// Currency
stylesheet.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.NumberingFormats>().InsertAt<DocumentFormat.OpenXml.Spreadsheet.NumberingFormat>(
new DocumentFormat.OpenXml.Spreadsheet.NumberingFormat()
{
NumberFormatId = 164,
FormatCode = "\"" + System.Globalization.CultureInfo.CurrentUICulture.NumberFormat.CurrencySymbol + "\"\\ " + "#,##0.00"
},0);
Thanks #Vadim for replying.
I tried to improve above suggestion because I tried same and didn't get $ sign with negative value. I applied following changes and fixed the $ sign issue with negative values.
stylesheet.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.NumberingFormats>().InsertAt<DocumentFormat.OpenXml.Spreadsheet.NumberingFormat>(
new DocumentFormat.OpenXml.Spreadsheet.NumberingFormat()
{
NumberFormatId = 164,
FormatCode = "\"" + System.Globalization.CultureInfo.CurrentUICulture.NumberFormat.CurrencySymbol + "\"\\ " + "#,##0.00;" + "\"(" + System.Globalization.CultureInfo.CurrentUICulture.NumberFormat.CurrencySymbol + "\"\\ " + "#,##.00)[Red];0.00"
}, 0);
Output : for positive values $ 1.23
for negative values ($ 1.23) { font color is read)
How about changing the text direction of the cell? Worked for me.

Convert Standard Numeric Format with culture to Custom Numeric Format

In C#, is there a way to get the equivalent custom numeric format for a standard numeric format with a specified user's culture?
Examples (not sure my conversion are right) :
C3 in fr-FR = 0.000 '€'
D2 = 0.00
P0 = %#0
See those links :
http://msdn.microsoft.com/en-us/library/dwhawy9k(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/0c899ak8(v=vs.110).aspx
Given a CultureInfo you can examine the NumberFormat property of type NumberFormatInfo to get all the information that .NET uses when formatting different number types. E.g.:
var frenchCultureInfo = CultureInfo.GetCultureInfo("fr-FR");
Console.WriteLine(frenchCultureInfo.NumberFormat.CurrencySymbol);
This will print €. To reconstruct the complete format you will have to inspect multiple properties on the NumberFormat property. This can become quite tedious. As an experiment I have tried to write the code necessary to format a Decimal using the C format specifier:
var value = -123456.789M;
var cultureInfo = CultureInfo.GetCultureInfo("as-IN");
var numberFormat = cultureInfo.NumberFormat;
// Create group format like "#,##,###".
var groups = numberFormat
.CurrencyGroupSizes
.Reverse()
.Select(groupSize => new String('#', groupSize));
var format1 = "#," + String.Join(",", groups);
// Create number format like "#,##,##0.00".
var format2 = format1.Substring(0, format1.Length - 1)
+ "0." + new String('0', numberFormat.CurrencyDecimalDigits);
// Format the number without a sign.
// Note that it is necessary to use the correct CultureInfo here.
var formattedNumber = Math.Abs(value).ToString(format2, cultureInfo);
// Combine sign, currency symbol and number.
var currencyPositivePatterns = new Dictionary<Int32, String> {
{ 0, "{0}{1}" },
{ 1, "{1}{0}" },
{ 2, "{0} {1}" },
{ 3, "{1} {0}" }
};
var currencyNegativePatterns = new Dictionary<Int32, String> {
{ 0, "({0}{1})" },
{ 1, "-{0}{1}" },
{ 2, "{0}-{1}" },
{ 3, "{0}{1}-" },
{ 4, "({1}{0})" },
{ 5, "-{1}{0}" },
{ 6, "{1}-{0}" },
{ 7, "{1}{0}-" },
{ 8, "-{1} {0}" },
{ 9, "-{0} {1}" },
{ 10, "{1} {0}-)" },
{ 11, "{0} {1}-" },
{ 12, "{0} -{1}" },
{ 13, "{1}- {0}" },
{ 14, "({0} {1})" },
{ 15, "({1} {0})" }
};
var currencyPattern = value >= Decimal.Zero
? currencyPositivePatterns[numberFormat.CurrencyPositivePattern]
: currencyNegativePatterns[numberFormat.CurrencyNegativePattern];
var formattedValue = String.Format(
currencyPattern,
numberFormat.CurrencySymbol,
formattedNumber
);
The value of formattedValue is ₹ -1,23,456.79 which is the same as you get when evaluating value.ToString("C", cultureInfo). Obviously, the later is much simpler.
Note that some currency symbols can contain . or ' which have special meaning in a custom numeric format. As a result of this you cannot always create a custom format string to replace C. E.g. for the da-DK culture the C format for a positive number is equivalent to kr. #,##0.00 except the dot after kr will make it impossible to use that format. Instead you have to use an approach where the currency symbol is added after the number has been formatted, or alternatively you can escape the problematic character.
Afaik unlike decimal separator or thousands separator, there is no format string for the cultures currency. Maybe this is due to the fact that a number is always the same in every culture, but an amount of money is different according to the currency. Thus, you would have to know the currency in advance.
However, if you do know the currency in advance, you can just use the currency symbol as a normal literal character.
Thus, you could use "0.000 €" (don't French people use the , as their decimal separator?).
If you know the culture in advance, you can get the format string that's used for currency and use it yourself.
In your example, you would retrieve the CultureInfo object for the fr-FR culture using this:
CultureInfo French = new CultureInfo("fr-FR");
You could just pass this CultureInfo object to the ToString() method, or you could get the NumberFormatInfo object from the CultureInfo:
NumberFormatInfo numberFormat = French.NumberFormat;
The NumberFormatInfo object has the following properties: CurrencySymbol, CurrencyDecimalDigits, CurrencyDecimalSeparator, 'CurrencyGroupSeparator,CurrencyGroupSizes`. Using them, you can construct your own format string:
string fmt = numberFormat.CurrencySymbol + "#" + numberFormat.CurrencyGroupSeparator;
for ( int i = 0; i < numberFormat.CurrencyGroupSizes - 1; i++ )
fmt += "#";
fmt += "0" + numberFormat.CurrencyDecimalSeparator;
for ( int d = 0; i < numberFormat.CurrencyDecimalDigits; i++ )
fmt += "0";
There are two other properties of the NumberFormatInfo class called CurrencyNegativePattern and CurrencyPositivePattern, which tell you where the decimal symbol & sign go, or whether to put negative values in parentheses. I'll leave it to you to decide if you need these & write the code necessary to build the format string.

Format custom numeric string with fixed character count

I need to convert any number in a fixed format with a fixed amount of characters. Means 1500 and -1.5 or 0.025 need to have the same length. I also have to give the format in this form: Format = "{???}";
When i type Format = "{0000}"; i can limit 1500 to "1500", but -1.5 -> "-0001.5" means i have too much numbers after the point.
Negative sign place can be done with Format = "{ 0.0;-0.0; 0.0}".
How can i fix the count of the numbers for different numbers?
The length of the string doesn't matter, the most important is the equal length.
Examples:
1500 -> " 1500.000" or " 1500"
-1500 -> "-1500.000" or "- 1500" or " -1500"
1.5 -> " 1.500" or " 1.5"
-0.25-> " -0.250" or "- 0.25"
0.00005 -> " 0.000" or " 0"
150000-> " 150000.0" or " 150000"
15000000 " 15000000"
Edit:
I want to Format an y-Axis of a Chart. I can't use something like value.ToString("???") i need to use chartArea.AxisY.LabelStyle.Format = "{???}";
Why don't use formatting? "F3" forces 3 digits after decimal point and PadLeft ensures the overall length
Double value = 1500.0;
// 3 digits after decimal point, 9 characters length
String result = value.ToString("F3").PadLeft(9, ' ');
0 -> 0.000
1500.0 -> 1500.000
-1500.0 -> -1500.000
-0.25 -> -0.250
Another (similar) possibility is String.Format:
Double value = 1500.0;
// Put value at place {0} with format "F4" aligned to right up to 9 symbols
String result = String.Format("{0:9,F4}", value);
Try it > result = Math.Round(yourValue, 3);
Check full reference here !
you cannot achieve this by a simple format function
string result = string.Empty;
var array = dec.ToString().Split('.');
if (dec > 0)
{
result = array[0].PadLeft(9).Remove(0, 9);
if (array.Count() > 1)
{
result += '.' + array[1].PadRight(3).Remove(3);
}
}
else
{
result = "-"+array[0].PadLeft(9).Remove(0, 9);
if (array.Count() > 1)
{
result += '.' + array[1].PadRight(3).Remove(3);
}
}

Format decimal value to string with leading spaces

How do I format a decimal value to a string with a single digit after the comma/dot and leading spaces for values less than 100?
For example, a decimal value of 12.3456 should be output as " 12.3" with single leading space. 10.011 would be " 10.0". 123.123 is "123.1"
I'm looking for a solution, that works with standard/custom string formatting, i.e.
decimal value = 12.345456;
Console.Write("{0:magic}", value); // 'magic' would be a fancy pattern.
This pattern {0,5:###.0} should work:
string.Format("{0,5:###.0}", 12.3456) //Output " 12.3"
string.Format("{0,5:###.0}", 10.011) //Output " 10.0"
string.Format("{0,5:###.0}", 123.123) //Output "123.1"
string.Format("{0,5:###.0}", 1.123) //Output " 1.1"
string.Format("{0,5:###.0}", 1234.123)//Output "1234.1"
Another one with string interpolation (C# 6+):
double x = 123.456;
$"{x,15:N4}"// left pad with spaces to 15 total, numeric with fixed 4 decimals
Expression returns: " 123.4560"
value.ToString("N1");
Change the number for more decimal places.
EDIT: Missed the padding bit
value.ToString("N1").PadLeft(1);
Many good answers, but this is what I use the most (c# 6+):
Debug.WriteLine($"{height,6:##0.00}");
//if height is 1.23 => " 1.23"
//if height is 0.23 => " 0.23"
//if height is 123.23 => "123.23"
All above solution will do rounding of decimal, just in case somebody is searching for solution without rounding
decimal dValue = Math.Truncate(1.199999 * 100) / 100;
dValue .ToString("0.00");//output 1.99
Note the "." could be a "," depending on Region settings, when using string.Format.
string.Format("{0,5:###.0}", 0.9) // Output " .9"
string.Format("{0,5:##0.0}", 0.9) // Output " 0.9"
I ended up using this:
string String_SetRPM = $"{Values_SetRPM,5:##0}";
// Prints for example " 0", " 3000", and "24000"
string String_Amps = $"{(Values_Amps * 0.1),5:##0.0}";
// Print for example " 2.3"
Thanks a lot!

Categories

Resources