How to format Double with dot? - java

How do I format a Double with String.format to String with a dot between the integer and decimal part?
String s = String.format("%.2f", price);
The above formats only with a comma: ",".

String.format(String, Object ...) is using your JVM's default locale. You can use whatever locale using String.format(Locale, String, Object ...) or java.util.Formatter directly.
String s = String.format(Locale.US, "%.2f", price);
or
String s = new Formatter(Locale.US).format("%.2f", price);
or
// do this at application startup, e.g. in your main() method
Locale.setDefault(Locale.US);
// now you can use String.format(..) as you did before
String s = String.format("%.2f", price);
or
// set locale using system properties at JVM startup
java -Duser.language=en -Duser.region=US ...

Based on this post you can do it like this and it works for me on Android 7.0
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
DecimalFormat df = new DecimalFormat("#,##0.00");
df.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.ITALY));
System.out.println(df.format(yourNumber)); //will output 123.456,78
This way you have dot and comma based on your Locale
Answer edited and fixed thanks to Kevin van Mierlo comment

If it works the same as in PHP and C#, you might need to set your locale somehow. Might find something more about that in the Java Internationalization FAQ.

Related

Why does the NumberFormat returns blank fields?

So a few days ago I encountered a weird problem however, I didn't change any that kind of code. The problem is the format I'm getting from my method which I used for years. All commas are now spaces (blank fields) and I have no idea what is causing this.
public static String toFancyCost(int num) {
return NumberFormat.getInstance().format((Integer) num);
}
Before even this happened the String I received was looking like for example 2,181,273 and not like 2 181 273.
You must have changed your system locale by accident. The implementation of NumberFormat.getInstance() (on 1.8.0_131):
public final static NumberFormat getInstance() {
return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
}
It uses formatting specified by the default locale. and the java docs on Locale.getDefault say:
The Java Virtual Machine sets the default locale during startup based
on the host environment. It is used by many locale-sensitive methods
if no locale is explicitly specified. It can be changed using the
setDefault method.
If you were to use NumberFormat.getInstance(Locale) you can specify which locale the NumberFormat should use.
Your systems default local is using a space as thousands separator, number format retured by getInstance() uses settings from system's default local.
As commented above, somehow the system default may have been modified. Let's stick the code to set the locale when formatting by using below to avoid any issues.
int number = 345678987;
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);// Locale.US or any other locale you required
String numberAsString = numberFormat.format(number);
System.out.println(numberAsString);
response:
345,678,987
when I use the below for example with Locale.CANADA_FRENCH
int number = 345678987;
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.CANADA_FRENCH);
String numberAsString = numberFormat.format(number);
System.out.println(numberAsString);
response:
345 678 987
So in your case also locale may have been causing issues, so please explictly set locale.

Java DecimalFormat - incorrect number format in linux

I have a problem with parsing decimal number in Linux environment. When I parse in Windows, everything's all right.
Below, code snippet
String price;
DecimalFormat FORMATTER = (DecimalFormat)DecimalFormat.getInstance();
double customPrice = FORMATTER.parse(price).doubleValue();
And results
When price='9' Then customPrice='9.0' - it is ok
When price='1,00' Then customPrice='100.0' - it is wrong
When price='25,00' Then customPrice='2500.0' - it is wrong
Can you tell me what the problem is ?
Thanks
Read here here about locales, probably you're using en_US which causes the ',' symbol to separate groups of thousands.
you can use also
DecimalFormatSymbols unusualSymbols = new DecimalFormatSymbols(currentLocale);
unusualSymbols.setDecimalSeparator(',');
DecimalFormat weirdFormatter = new DecimalFormat(strange, unusualSymbols);
weirdFormatter.setGroupingSize(4);
to state your own sepeartors
You can change the decimal separator of DecimalFormat. The easiest way by using a NumberFormat with the desired locale, e.g.:
NumberFormat FORMATTER = NumberFormat.getNumberInstance(Locale.GERMAN);
double customPrice = FORMATTER.parse(price).doubleValue();

Java NumberFormatException Legacy Code

I have a legacy program (java 1.4) running under Tomcat/Jboss, however, i have copy it to a new server (java 1.7) and it throws the following exception.
java.lang.NumberFormatException: For input string: "0000000000000000009011,00"
sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1250)
java.lang.Double.valueOf(Double.java:504)
java.lang.Double.<init>(Double.java:597)
Since i don't have access to the source, is there any way to fix this? i haven't try with java 1.4 for the moment
You schould look to jvm parameters on old server. Your language parameters will change comma to dot actually so you do not need any code changes.
I think its not due to java version. Replace comma(,) with "" or period(.)
For example conside a string : String str = "0000000000000000009011,00";
Now you can try -
double result = Double.valueOf(str.replace(",", "."));
or
double result = Double.valueOf(str.replace(",", ""));
Rather use NumberFormat for parsing:
NumberFormat format = NumberFormat.getInstance(Locale.FRANCE);
Number number = format.parse("0000000000000000009011,00");
double d = number.doubleValue();
This way you can select the right locale for the number representation. In the example above I used France - they use a comma for the decimal point.

Setting Turkish and English locale: translate Turkish characters to Latin equivalents

I want to translate my Turkish strings to lowercase in both English and Turkish locale. I'm doing this:
String myString="YAŞAT BAYRI";
Locale trlocale= new Locale("tr-TR");
Locale enLocale = new Locale("en_US");
Log.v("mainlist", "en source: " +myString.toLowerCase(enLocale));
Log.v("mainlist", "tr source: " +myString.toLowerCase(trlocale));
The output is:
en source: yaşar bayri
tr source: yaşar bayri
But I want to have an output like this:
en source: yasar bayri
tr source: yaşar bayrı
Is this possible in Java?
If you are using the Locale constructor, you can and must set the language, country and variant as separate arguments:
new Locale(language)
new Locale(language, country)
new Locale(language, country, variant)
Therefore, your test program creates locales with the language "tr-TR" and "en_US". For your test program, you can use new Locale("tr", "TR") and new Locale("en", "US").
If you are using Java 1.7+, then you can also parse a language tag using Locale.forLanguageTag:
String myString="YASAT BAYRI";
Locale trlocale= Locale.forLanguageTag("tr-TR");
Locale enLocale = Locale.forLanguageTag("en_US");
Creates strings that have the appropriate lower case for the language.
I think this is the problem:
Locale trlocale= new Locale("tr-TR");
Try this instead:
Locale trlocale= new Locale("tr", "TR");
That's the constructor to use to specify country and language.
you can do that:
Locale trlocale= new Locale("tr","TR");
The first parameter is your language, while the other one is your country.
If you just want the string in ASCII, without accents, the following might do.
First an accented character might be split in ASCII char and a combining diacritical mark (zero-width accent). Then only those accents may be removed by regular expression replace.
public static String withoutDiacritics(String s) {
// Decompose any ş into s and combining-,.
String s2 = Normalizer.normalize(s, Normalizer.Form.NFD);
return s2.replaceAll("(?s)\\p{InCombiningDiacriticalMarks}", "");
}
Characters ş and s are different characters. Changing locale cannot help you to translate one to another. You have to create turkish-to-english characters table and do this yourself. I once did this for Vietnamic language that has a lot of such characters. You have to deal with 4 of 5, right? So, good luck!

DecimalFormat depending on system settings?

I'm having the strangest thing with a DecimalFormat.
I'm using it in an webapplication.
I setup some test and it keeps on failing with me locally.
A friend of me ran it and he was able to successfully ran the JUnit tests.
The strange part is that on our server the application runs it perfectly without any problems either.
Could it be that Java depends on the system settings like valuta and number settings?
Or could there be another reason?
This is how my piece of code looks like:
public String generateFormatPrice(double price) throws Exception {
DecimalFormat format1 = new DecimalFormat("#,##0.00");
String tmp = format1.format(price).replace(".", "&");
String[] tmps = tmp.split("&");
return tmps[0].replace(',', '.') + "," + tmps[1];
}
Thanks a lot in advance!
This code is indeed locale-specific. If your code depends on being in a locale such as the USA where "." is the decimal separator and "," is the thousands separator, and then you run this code on a server set to, for example, the German locale, it will fail.
Consider using this constructor, which allows you to explicitly specify which symbols you are using.
EDIT: as far as I can tell you are trying to format numbers using "." as the thousands separator and "," as the decimal separator. In other words, the format used in France and Germany. Here's one approach that will achieve this:
public static String generateFormatPrice(double price) {
final NumberFormat format = NumberFormat.getNumberInstance(Locale.GERMANY);
format.setMinimumFractionDigits(2);
format.setMaximumFractionDigits(2);
return format.format(price);
}
Also, you shouldn't be using a double to hold a monetary value - you are going to encounter some nasty bugs if you do that.

Categories

Resources