I am trying to format prices using DecimalFormat, but this isn't working for all variations.
DecimalFormat df = new DecimalFormat("0.##")
df.format(7.8)
df.format(85.0)
prints
7.80
and
85
but "7.79999" gets formatted as "7.8", not "7.80". I have tried doing things this way
DecimalFormat df = new DecimalFormat("0.00")
to force two dp, but then "85.0" gets formatted as "85.00" not "85"!
Is there a way of capturing all variations, so that prices are printed either as #, ##, or #.##? For example:
5, 55, 5.55, 5.50, 500, 500.40
There is a slight difference between these two formats. The "#.##" means it will print the number with maximum two decimal places whereas "#.00" means it will always display two decimal places and if the decimal places are less than two, it will replace them with zeros. see the example below with output.
public static final DecimalFormat df1 = new DecimalFormat( "#.##" );
public static final DecimalFormat df2 = new DecimalFormat( "#.00" );
System.out.println(df1.format(7.80));
System.out.println(df1.format(85));
System.out.println(df1.format(85.786));
System.out.println(df2.format(7.80));
System.out.println(df2.format(85));
System.out.println(df2.format(85.786));
And the output will be
7.8
85
85.79
7.80
85.00
85.79
This doesn't seem to be solved by a single formatter. I suggest you use "0.00" format and replace ".00" with an empty string.
public static String myFormat(double number) {
DecimalFormat df = new DecimalFormat("0.00");
return df.format(number).replaceAll("\\.00$", "");
}
I don't think it's possible, at least not with Java SE formatters. You need to make a custom formatter. I would do it like this
String res = df.format(number).replace(".00", "");
Use the BigDecimal number class instead:
e.g. if n is a BigDecimal,
then you can use
String s = NumberFormat.getCurrencyInstance().format(n);
By the way, it's best practice to use BigDecimal when working with money.
You can try with:
DecimalFormat df = new DecimalFormat("#.##",new DecimalFormatSymbols(Locale.US));
System.out.println(new java.text.DecimalFormat("#.##").format(5.00));
This will print 5
System.out.println(new java.text.DecimalFormat("#.00").format(500.401));
This will print 500.40
Related
I've already tried a way to format this whole number in decimal plus no solve the one that comes closest to the result hoping was using the BigDecimal plus it was very extensive. Where am I going wrong?
Double value = 20852;
DecimalFormat df = new DecimalFormat("0.00##");
String result = df.format(value);
result = 20852.00
expected outcome : 20.852
With decimal format you define how many decimal places are need to be set. The output is completely correct. It would create the desired output if you have double value = 20.852. What you want is to set the thousand sepeator:
DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
DecimalFormat df = new DecimalFormat("###,###.##", symbols);
As stated by your question, without changing anything to your number and to get the result your expressively required, you could do this with setting the dot character as a thousands separator :
Double value = 20852d;
DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
symbols.setGroupingSeparator('.');
DecimalFormat df = new DecimalFormat("##,000", symbols);
String result = df.format(value);
I am attempting to use the DecimalFormat java class for the first time, and I am running into a strange issue. I would like 125.295 to round to 125.30. I would think the format should automatically include the 0, but maybe I'm incorrect.
double num = 125.295;
DecimalFormat df = new DecimalFormat("#.##");
df.setRoundingMode(RoundingMode.HALF_UP);
String str = df.format(num);
System.out.println(str); //this is yielding 125.3 instead of 125.30
Please help and thank you in advance!
The DecimalFormat class treats '#' as "hide trailing zeroes" or '0' as "show the zeroes". As per the API for DecimalFormat:
0 Number Yes Digit
# Number Yes Digit, zero shows as absent
So you should use DecimalFormat("#.00") instead of DecimalFormat("#.##") if you want it to show trailing zeroes.
Try to use DecimalFormat like this:
double num = 125.295;
DecimalFormat df = new DecimalFormat("###.00");
System.out.println("sum (DecimalFormat) : " + df.format(num));
Output:
125.30
I want to round all of my numbers to 1 decimal place.
For example
22.0
-6.1
I am using:
DecimalFormat decimalFormat = new DecimalFormat("0.0");
middlePanelTextView.setText(decimalFormat.format(score.getElevationAngle()));
But whole numbers don't have a 0 appended to it.
-18 should be -18.0 etc.
instead my value shows up as -18.
.# represents a significant digit 0 doesn't.
.# represents and optional digit So try "###.#"
http://developer.android.com/reference/java/text/DecimalFormat.html
I'm not sure about the syntax: but the above article should give you all you need.
Try
middlePanelTextView.setText(""+decimalFormat.format(score.getElevationAngle()));
My TextView was cutting off the digits. My fault. Shrank font size.
Try using
DecimalFormat decimalFormat = new DecimalFormat("#.#");
as the constructor parameter instead.
Try using the following code:
DecimalFormat decimalFormat = new DecimalFormat("0.0#");
I have this little crazy method that converts BigDecimal values into nice and readable Strings.
private String formatBigDecimal(BigDecimal bd){
DecimalFormat df = new DecimalFormat();
df.setMinimumFractionDigits(3);
df.setMaximumFractionDigits(3);
df.setMinimumIntegerDigits(1);
df.setMaximumIntegerDigits(3);
df.setGroupingSize(20);
return df.format(bd);
}
It however, also produces a so called grouping separator "," that makes all my values come out like this:
xxx,xxx
I do need the separator to be a dot or a point and not a comma.
Does anybody have a clue of how to accomplish this little feat?
I have read this and in particular this to death now but I cannot find a way to get this done.
Am I approaching this the wrong way? Is there a much more elegant way of doing this? Maybe even a solution that accounts for different local number representations, since the comma would be perfect by European standards.
You can change the separator either by setting a locale or using the DecimalFormatSymbols.
If you want the grouping separator to be a point, you can use an european locale:
NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMAN);
DecimalFormat df = (DecimalFormat)nf;
Alternatively you can use the DecimalFormatSymbols class to change the symbols that appear in the formatted numbers produced by the format method. These symbols include the decimal separator, the grouping separator, the minus sign, and the percent sign, among others:
DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols(currentLocale);
otherSymbols.setDecimalSeparator(',');
otherSymbols.setGroupingSeparator('.');
DecimalFormat df = new DecimalFormat(formatString, otherSymbols);
currentLocale can be obtained from Locale.getDefault() i.e.:
Locale currentLocale = Locale.getDefault();
Europe is quite huge. I'm not sure if they use the same format all over. However this or this answer will be of help.
String text = "1,234567";
NumberFormat nf_in = NumberFormat.getNumberInstance(Locale.GERMANY);
double val = nf_in.parse(text).doubleValue();
NumberFormat nf_out = NumberFormat.getNumberInstance(Locale.UK);
nf_out.setMaximumFractionDigits(3);
String output = nf_out.format(val);
I.e. use the correct locale.
public String getGermanCurrencyFormat(double value) {
NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMAN);
nf.setGroupingUsed(true);
return "€ " + nf.format(value);
}
This worked in my case:
DecimalFormat df2 = new DecimalFormat("#.##");
df2.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ENGLISH));
BigDecimal does not seem to respect Locale settings.
Locale.getDefault(); //returns sl_SI
Slovenian locale should have a decimal comma. Guess I had strange misconceptions regarding numbers.
a = new BigDecimal("1,2") //throws exception
a = new BigDecimal("1.2") //is ok
a.toPlainString() // returns "1.2" always
I have edited a part of my message that made no sense since it proved to be due the human error (forgot to commit data and was looking at the wrong thing).
Same as BigDecimal can be said for any Java .toString() functions. I guess that is good in some ways. Serialization for example or debugging. There is an unique string representation.
Also as others mentioned using formatters works OK. Just use formatters, same for the JSF frontend, formatters do the job properly and are aware of the locale.
String money = output.replace(',', '.');
you could just use replace function before you return the string in the method
return df.format(bd).replace(",", ".")
This worked for me...
double num = 10025000;
new DecimalFormat("#,###.##");
DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance(Locale.GERMAN);
System.out.println(df.format(num));
I'd like to use Java's DecimalFormat to format doubles like so:
#1 - 100 -> $100
#2 - 100.5 -> $100.50
#3 - 100.41 -> $100.41
The best I can come up with so far is:
new DecimalFormat("'$'0.##");
But this doesn't work for case #2, and instead outputs "$100.5"
Edit:
A lot of these answers are only considering cases #2 and #3 and not realizing that their solution will cause #1 to format 100 as "$100.00" instead of just "$100".
Does it have to use DecimalFormat?
If not, it looks like the following should work:
String currencyString = NumberFormat.getCurrencyInstance().format(currencyNumber);
//Handle the weird exception of formatting whole dollar amounts with no decimal
currencyString = currencyString.replaceAll("\\.00", "");
Use NumberFormat:
NumberFormat n = NumberFormat.getCurrencyInstance(Locale.US);
double doublePayment = 100.13;
String s = n.format(doublePayment);
System.out.println(s);
Also, don't use doubles to represent exact values. If you're using currency values in something like a Monte Carlo method (where the values aren't exact anyways), double is preferred.
See also: Write Java programs to calculate and format currency
Try
new DecimalFormat("'$'0.00");
Edit:
I Tried
DecimalFormat d = new DecimalFormat("'$'0.00");
System.out.println(d.format(100));
System.out.println(d.format(100.5));
System.out.println(d.format(100.41));
and got
$100.00
$100.50
$100.41
Try using
DecimalFormat.setMinimumFractionDigits(2);
DecimalFormat.setMaximumFractionDigits(2);
You can check "is number whole or not" and choose needed number format.
public class test {
public static void main(String[] args){
System.out.println(function(100d));
System.out.println(function(100.5d));
System.out.println(function(100.42d));
}
public static String function(Double doubleValue){
boolean isWholeNumber=(doubleValue == Math.round(doubleValue));
DecimalFormatSymbols formatSymbols = new DecimalFormatSymbols(Locale.GERMAN);
formatSymbols.setDecimalSeparator('.');
String pattern= isWholeNumber ? "#.##" : "#.00";
DecimalFormat df = new DecimalFormat(pattern, formatSymbols);
return df.format(doubleValue);
}
}
will give exactly what you want:
100
100.50
100.42
You can use the following format:
DecimalFormat dformat = new DecimalFormat("$#.##");
I know its too late. However following worked for me :
DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols(Locale.UK);
new DecimalFormat("\u00A4#######0.00",otherSymbols).format(totalSale);
\u00A4 : acts as a placeholder for currency symbol
#######0.00 : acts as a placeholder pattern for actual number with 2 decimal
places precision.
Hope this helps whoever reads this in future :)
You can try by using two different DecimalFormat objects based on the condition as follows:
double d=100;
double d2=100.5;
double d3=100.41;
DecimalFormat df=new DecimalFormat("'$'0.00");
if(d%1==0){ // this is to check a whole number
DecimalFormat df2=new DecimalFormat("'$'");
System.out.println(df2.format(d));
}
System.out.println(df.format(d2));
System.out.println(df.format(d3));
Output:-
$100
$100.50
$100.41
You could use the Java Money API to achieve this. (although this is not using DecialFormat)
long amountInCents = ...;
double amountInEuro = amountInCents / 100.00;
String customPattern;
if (minimumOrderValueInCents % 100 == 0) {
customPattern = "# ¤";
} else {
customPattern = "#.## ¤";
}
Money minDeliveryAmount = Money.of(amountInEuro, "EUR");
MonetaryAmountFormat formatter = MonetaryFormats.getAmountFormat(AmountFormatQueryBuilder.of(Locale.GERMANY)
.set(CurrencyStyle.SYMBOL)
.set("pattern", customPattern)
.build());
System.out.println(minDeliveryAmount);
printf also works.
Example:
double anyNumber = 100;
printf("The value is %4.2f ", anyNumber);
Output:
The value is 100.00
4.2 means force the number to have two digits after the decimal. The 4 controls how many digits to the right of the decimal.