Xtend: Generators produce comma instead of point - java

I am using template expressions for generating files. For example:
def generateStuff(MyObject in) {
'''
This is the wrong value: «calculatedoubleValue(in.doubleValue)»
'''
}
The value of doubleValue is an double. But the generator produces a comma instead of an point, as delimiter.
I also tried using DecimalFormat, for example:
def generateStuff(MyObject in) {
var df = new DecimalFormat("0.000");
var calculated = calculatedoubleValue(in.doubleValue)
'''
This is the wrong value: «df.format(calculated)»
'''
}
But unfortunately it still produces a comma. I wonder, because it only happens to a few values and not to all, allthough I am only working with doubles. Another strange thing is, that it produces points, when debugging (Runtime Eclipse Application) but commas after I export the application as an Eclipse product.
What could be the cause for this?

Within template expressions toString() is invoked on any values (see StringConcatenation).
Double.toString will always use '.', so the issue must be somewhere else.
Maybe the problem is in your 'calculatedDouble' method?

Although I don't have much info about your environment, based on your example code you do not directly use Double.toString() (that always uses . as decimal separator) but DecimalFormat which is locale-sensitive.
When DecimalFormat is constructed by using the DecimalFormat(String), it will use the default "format locale". In some locales the decimal separator is . (e.g. in English) but in other locales it is , (e.g. in Hungarian). See the API docs for more details.
Proposed solutions to your problem:
Ensure that the application uses the same locale in each case.
Set the locale-specific formatting options explicitly.
Real code:
#Test
public void testDecimalFormat() {
assertEquals("0.000", new DecimalFormat("0.000", new DecimalFormatSymbols(Locale.ENGLISH)).format(0.0));
assertEquals("0,000", new DecimalFormat("0.000", new DecimalFormatSymbols(new Locale("hu"))).format(0.0));
}

Related

String with EX, EEX, EXP or EE scientific notation to double

In my code I am receiving numeric values as strings from different sources. One of the source is sending me this kind of value:
-6.535402781EX-05
After few tests I know that EX format is not handled by Double.valueOf() method. NumberFormatException is thrown.
I figured out easy workaround:
String val = "-6.535402781EX-05".replace("X", "");
Actually it is working, but I am not sure if that's best solution. I saw also EEX, EE and EXP. Question: How to protect my code for this kind of edge cases?
You may want to use replaceAll witha regex instead of replace if those are the only possible values:
String[] val = {"-6.535402781EX-05","-6.535402781EEX-05","-6.535402781EE-05","-6.535402781EXP-05"};
for(String v :val){
System.out.println(v.replaceAll("[EXP]{2,}", "E"));
}
Would a simple regular expression do the trick for you? You could first convert the different input formats to your known input format that can be handled by Double.valueOf().
String pattern = "(\\D?)(\\d+)(\\.?)(\\d+)(\\D+)(\\d+)";
List<String> inputs = Arrays.asList("-6.535402781EX-05",
"-6.535402781EXP-05",
"-6.535402781EE-05",
"-6.535402781E-05",
"6.535402781E-05",
"6.535402781",
"-6.535402781",
"6.5",
"6");
inputs.forEach((String in) -> System.out.println(in.replaceAll(pattern, "$1$2$3$4E-$6")));
The inputs in my example should be converted to the following and parsing them should be possible with Double.valueOf().
-6.535402781E-05
-6.535402781E-05
-6.535402781E-05
-6.535402781E-05
6.535402781E-05
6.535402781
-6.535402781
6.5
6
You should be careful to add enough unit test cases for all input formats you want to support.

How to customize currency formatting in MessageFormat in ICU4J

I have a system that generates a lot of documents. Its contents are defined in ResourceBundles.
I want to customize the way MessageFormat prints currency values. Sometimes I want it to display currencies without fraction digits (but not always).
This should be working as expected but it is not:
System.err.println(
com.ibm.icu.text.MessageFormat.format(
"{0,number,\u00A4#}",
new com.ibm.icu.util.CurrencyAmount(1,
com.ibm.icu.util.Currency.getInstance("USD"))));
Unfortunately it prints out:
US$1,00
Does anyone of you use custom formats for currency in resource bundle 'properties' files?
I don't want to change it system wide.
And by the way this works fine with java.text.MessageFormat.
OK, I read your question once again.
I don't really know why you want to chop down the cents part (in US, it makes sense in Korea or Japan as they don't use them at all).
Anyway, I don't think it is a good idea to just cut-off cents part, but if you want to do it, it is as simple as using NumberFormat with setMaximumIntegerDigits(int).
BTW, I still don't know I know why by using resource bundles you can't use NumberFormat.
You still can call formatter in MessageFormat.format():
NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(Locale.US);
currencyFormatter.setMaximumFractionDigits(0);
System.err.println(MessageFormat.format("Some amount: {0}.",
currencyFormatter.format(1d)));
Predictably it prints out:
Some amount: $1.
If you need to retain the currency, I'd suggest to play with setCurrency(Currency) method by retain local format - you are asking this question in Internalization tag anyway.
Edit: Including information about MessageFormat capabilities
If you need to use custom currency formats for a Locale, you actually need to instantiate MessageFormat class (regular static MessageFormat.format(String, Object...) won't work in web applications for it uses default Locale - Locale.getDefault(Locale.Category.FORMAT) in Java 7 - server Locale if you prefer).
So what you really want is to write a helper method (sorry, no bonus) that will look similar to this (out of memory, sorry):
public static String format(String pattern, Locale locale, Object... args) {
final String emptyPattern = "";
final FieldPosition zero = new FieldPosition(0);
MessageFormat fmt = new MessageFormat(emptyPattern, locale);
StringBuffer buf = new StringBuffer(); // I just love it...
fmt.applyPattern(pattern);
fmt.format(args, buf, zero);
return buf.toString();
}
For performance reasons, you might think of creating StringBuffer once and then clean it all the time, but I leave optimizations to yourself.
You also would need to modify patterns a bit and I will explain in a moment why:
String pattern = "{1}{0,number,\u00A4#}";
You would need to pass the amount and the currency symbol and left to translators where to place the symbol and how to format value for a Locale (don't forget to add comments to properties file!).

How to print upto two decimal places in java using string builder?

hi i am trying to print after dividing in string builder and printing that string builder let show me my code ,
string.append("Memomry usage:total:"+totalMemory/1024/1024+
"Mb-used:"+usageMemory/1024/1024+
" Mb("+Percentage+"%)-free:"+freeMemory/1024/1024+
" Mb("+Percentagefree+"%)");
in above code "totalmemory" and "freememory" is of double type having bytes value in point not null so i divide it by "1024" two times to get it in "Mb" and "string" is variable of string builder after using this code i am simply printing it a am getting result as shown below,
Used Memory:Memomry usage:
total:13.3125Mb-used:0.22920989990234375Mb (0.017217645063086855%)
-free:13.083290100097656Mb (0.9827823549369131%)
i want to get percentage in twodecimal place and values of used and free memory in mb like this "used:2345.25" in this pattren remember
Hopes for your suggestions
Thanks in Advance
How about String.format()?
System.out.println(String.format("output: %.2f", 123.456));
Output:
output: 123.46
Try like this
double d = 1.234567;
DecimalFormat df = new DecimalFormat("#.##");
System.out.print(df.format(d));
Using DecimalFormat, we can format the way we wanted to see.
You can use DecimalFormat to print out to two decimal places. So, to print x = 2345.2512 with two decimal places, you would write
NumberFormat f = new DecimalFormat("#.00");
System.out.println(f.format(x));
which will print 2345.25.
Even though it is possible to use NumberFormat and it's subclass DecimalFormat for this issue,
these classes provide a lot of functionality that may not be required for your application.
If the objective is just pretty printing, I would recommend using the format function of the String class. For your specific code it would look like this:
string.append(String.format("Memomry usage:total:%1.2f Mb-used:%1.2f Mb(%1.2f %%)-free:%1.2f Mb(%1.2f %%)",totalMemory/1024/1024,usageMemory/1024/1024,Percentage,freeMemory/1024/1024,Percentagefree));
If you are intending to specify a standard format in which all numbers are represented irrespective of whether they are being parsed from strings or formatted to strings, then I would recommend using singletons of the *Format classes. They allow you to use standard formats and also to pass format descriptions between methods.
Hope that helps you select the right method to use in your application.

Inserting custom String between number and decimal - Java DecimalFormat

Hello and thank you in advance for the help.
I am having some trouble formatting using a Java function to mark up a price in HTML.
It seems that, no matter what I do, I cannot insert custom content between the numbers and the decimal (throws Illegal Argument Exception). Is there any known way to achieve the following:
NumberFormat nf = getNumberFormat("'<span class=\"dollars\">'##'</span></span class=\"decimal\">'.'</span></span class=\"cents\">'00'</span>'", locale);
nf.format(number);
Assume locale and number are correctly initialized.
If you look at the docs for DecimalFormat you'll see that they talk about the prefix and the suffix text - but not putting arbitrary text within a number.
It sounds like you should basically write this bit of formatting yourself - possibly using DecimalFormat for each section of the number.
You might consider using String.format(String pattern, Object... arguments). You can pass your simply formatted numbers as arguments.

Format negative amount of USD with a minus sign, not brackets (Java)

How do I get NumberFormat.getCurrencyInstance() to print negative USD currency values with a minus sign?
It requires a little tweaking of the DecimalFormat returned by NumberFormat.getCurrencyInstance() to do it in a locale-independent manner. Here's what I did (tested on Android):
DecimalFormat formatter = (DecimalFormat)NumberFormat.getCurrencyInstance();
String symbol = formatter.getCurrency().getSymbol();
formatter.setNegativePrefix(symbol+"-"); // or "-"+symbol if that's what you need
formatter.setNegativeSuffix("");
IIRC, Currency.getSymbol() may not return a value for all locales for all systems, but it should work for the major ones (and I think it has a reasonable fallback on its own, so you shouldn't have to do anything)
Here is one I always end up using either in a java class or via the fmt:formatNumber jstl tag:
DecimalFormat format = new DecimalFormat("$#,##0.00;$-#,##0.00");
String formatted = format.format(15.5);
It always produces at least a $0.00 and is consistent when displayed. Also includes thousands seperators where needed. You can move the minus sign in front of the dollar sign if that is your requirement.
It's probably best to create your own DecimalFormat if you want a specific format rather than relying on the default.
Edit: You could probably also cast the result of NumberFormat.getCurrencyInstance() to DecimalFormat and adjust it to your preferences.
Try:
NumberFormat.getCurrencyInstance(Locale.CANADA);
NumberFormat.getCurrencyInstance(Locale.UK);
Why poi REFUSES to support the FIRST option in excel currency formatting is beyond me!
I don't like using the DecimalFormat for currency because your end cell value becomes a non-numeric with the introduction of the currency symbol. While working for a major financial institution, I was tasked with resolving this formatting issue. The core idea of this change is, because POI refuses to be reasonable and have comprehensive support of Excel's native options, I will infiltrate their code and change their values at the core. The following is my WORKAROUND:
private static final String CURRENCY_FORMAT_OVERRIDE = "\"$\"#,##0.00_);-\"$\"#,##0.00";
private static final String CURRENCY_FORMAT_TARGET = "\"$\"#,##0.00_);(\"$\"#,##0.00)";
static { // static class level initializer
Field field = org.apache.poi.ss.usermodel.BuiltinFormats.class.getDeclaredField("_formats");
field.setAccessible(true);
String[] _formats = (String[])field.get(new org.apache.poi.ss.usermodel.BuiltinFormats());
for(int i = 0; i < _formats.length; ++i) {
if(_formats[i].equals(CURRENCY_FORMAT_TARGET)) {
_formats[i]=CURRENCY_FORMAT_OVERRIDE;
System.out.println("TAKE THAT, POI!!!");
}
}
}
Since I faced this problem again, I did some research and found a more resilient solution provided by the ICU:
NumberFormatter
.withLocale(...)
.unit(Currency.getInstance("USD"))
.sign(SignDisplay.AUTO) // "123", "0", and "-123"
.format(123)
.toString();
Check the API documentation of NumberFormatter for more details.

Categories