Conversion of a string to a bigDecimal - java

My problem is that I have a user input field, which is a textfield, and I have to convert it to a bigDecimal for use at the database.
2,50 --> 2,50
2.50 --> 2,50
2.5 --> 2,50
1200 --> 1200 (or 1200,00)
1.200 --> 1200 (or 1200,00)
1.200,50 --> 1200,50
1,200.50 --> 1200,50
Is there a simple way to convert all these kind of inputs? The use of valueOf or parseDouble does not do the job. I also tried the DecimalFormatter, but I can't find the correct format.

DecimalFormat is the way to go - get the appropriate DecimalFormat for the user's locale, and call setParseBigDecimal(true) so that it parses to BigDecimal rather than double.
Note that you really need to know the right locale - otherwise "1,251" could mean "a bit more than one and a quarter" or "the integer 1251". Admittedly you could try to parse it with every format available and guess which is the right one out of formats that succeed, but that doesn't sound like a great idea to me.

Related

Java to C# format specifiers

I am new to C# having used Java.
I am looking to output an expression of 4.5 - 2.7... In Java I would simply write System.out.format("%.2f\n", 4.5 - 2.7);
In C#, I have used Console.WriteLine(4.5 - 2.7); but I am looking to print 2 decimal places.
Could someone be so kind as to explain how I achieve this?
Use String.Format (Link To Documentation)
Use the format {Parameter Number:Decimal Places}
Console.WriteLine(String.Format(" We are going to format 15.6345 as {0:0.00}",15.6345));
Test it here!.
Good luck!
EDIT / Clarification
By Parameter Number, String.Format takes all other inputs after the first input of a string to be values to format and place into the string.
Every time {x:yyz} appears in the string, System.String.Format will format x in the style yyz, where x is the index of the value passed in.
In my example above, 15.6345 is x, and the format 0.00 is yyz.
You could format 2 numbers or repeat one by going:
Console.WriteLine(String.Format(" We are going to format 15.6345 as {0:0.00} , the format 3.123 as 3.1 {1:0.0} , then repeat 15.6345 as 15.6 {0:0.0}",15.6345,3.123));

Sending money properties using REST api - quotation marks or not?

Is there any standard as for sending amounts in rest ?
What is the proper way to send POST request with body with amount field and where can I find explanation ?
"amount": "2.222222222"
or
"amount": 2.222222222
Note that REST isn't always JSON. You appear to be actually asking about JSON-encoding money values.
If you're consuming an existing JSON API, you don't have a choice to make: the API spec will tell you whether the field is expected to be a string or a number.
If you're designing a new API, you need to make this choice.
The JSON standard specifies how to encode a number containing a decimal point, but it doesn't specify anything about how the decoded number should be represented. It's very likely that a decoding library would decode it as a floating-point number.
With very few exceptions, it's a bad idea to use floating-point for money: Why not use Double or Float to represent currency?. For this reason my advice would be use strings to transfer money values, and explicitly convert in both the client and the server. This means leaves less scope for intermediate JSON handling code to change the value.
Also note that a JSON Number has no unit. If you encode a monetary value as a string, you have the option to include a currency in the format: "£123.45". Of course both the encoder and the decoder would need to know about this format.

Is BigDecimal necessary if no calculations are done with the monetary amount?

I have a Java program that reads data from a database, and shows it on a user interface. One of these data types is a money amount - and so it automatically triggers me to use BigDecimal as explained here . However in my case I don't do anything with this field except
render it on the UI.
give it another application (over http) who may write it into another database.
Considering the data in the database is of a type similar to double, I don't see any advantage into casting that double precision database field into a BigDecimal because it just gets converted to a string anyway (either for the UI, or for the webservice).
Am I missing something?
There is no requirement to use BigDecimal for monetary values however you must ensure that the amount is stored precisely without any rounding or precision problems normally encountered in float or double data types.
There are few ways to achieve this:
Java 9 comes with JSR 354: Money and Currency API classes e.g. MonetaryAmount.
Store the amount as long using the smallest meaningful currency unit e.g. for USD it's the cent. Look out because some currencies don't use fractional units e.g. YEN.
Mentioned BigDecimal.
Store the amount as String if it doesn't require any processing on your side. It's an ugly approach but if you are only passing the amounts around it might do e.g. read from XML and expose using REST API.

How to customize number format in freemarker?

I am using freemarker and trying to display numbers in this format: $3,343,434.00 for example. This was easily taken care of by using ${total?string.currency} (assuming "total" is some number).
However, when I have negative numbers, it's showing them like this: ($343.34) instead of this: -$343.34. I need the negative sign instead of the parenthesis. Is there a way I could customize the formatting so it does everything that the string.currency did but replace the negative value behavior? I am relatively new to freemarker, so detailed responses are appreciated!
You can also try ?string(",##0.00"). However in this case you need to explicitly add $ and - sign would be after $ in case of negative numbers.
<#local total = 3343434/>
$ ${total?string(",##0.00")} //$ 3,343,434.00
<#local total = -3343434/>
$ ${total?string(",##0.00")} //$ -3,343,434.00
OR in case if you want what was expected you can replace the strings.
<#local total = -3343434/>
<#local total = "$ " + total?string(",##0.00")/>
${total?replace('$ -','- $')} //- $3,343,434.00
Update: Since FreeMarker 2.3.24 you can define named custom number formats, which can be an alias to a number format pattern (or even a formatter implemented in Java, but that level of flexibility isn't needed in this case). So add a custom number format called "money" as an alias to "¤,##0.00" to the FreeMarker configuration, and then you can write something like ${total?string.#money}. See: http://freemarker.org/docs/pgui_config_custom_formats.html
Currently FreeMarker just uses the formatting facility of the Java platform, so it's only as configurable as that (assuming you want to use ?string and ?string.somethingPredefiendHere). Which is not much... but, in general, the formatting categories provided by the Java platform is not fine-gradient enough anyway, I mean, you don't have application-domain categories like, price-of-product, a salary, a price on the stock, etc. (This demand is more frequent with non-currency numbers though.) So I think, generally, you want to make a formatter function, that you can use like ${salary(someNumber)}, ${price(someNumber)}, etc. Those functions can be implemented in a commonly #included/#imported template like a #function or in Java by using #assign salary = 'com.example.SalarayMethod'?new() in place of #function, where com.example.SalarayMethod is a TemplateMethodModelEx.
How about taking a mod of your number, convert it to the required string format and finally add a '-' prefix to the final string. You can retain the default format in just two steps.
Freemarker uses the currency formatting provided by the Java platform.
It requires a little tweaking of the DecimalFormat returned by NumberFormat.getCurrencyInstance() (which is what is called when you call .currency). You can see examples of it here.
However, that said it will likely be more effective for you to create a macro in freemarker to call which will handle your specific formatting.
Sorry for not having an example of what that macro would look like, but it's a good starter into macros in freemarker since you are just learning.
You might investigate if you can supply a custom format using the exposed configuration for number formats that will meet your needs.
If you want to maintain the default currency formatting (in case you need to use a locale other than '$'), you can just replace the parentheses like so:
${transaction.amount?string.currency?replace("(","-")?replace(")","")}
This will work without error regardless of if a number is negative or positive.
TIP: Make sure the number is actually a number with the ?number directive before converting to a currency format

How to format Numbers in Velocity Templates?

I am getting a java object in my velocity template. The object has a double value which I want to format to 2 decimal places and display it in my template.
The class for which im getting an object is something like this
Class Price
{
double value;
String currency;
}
In my velocity template, im getting the value like this
$price.value
but I need to format it to 2 decimal places before displaying it.
I want to convert
23.59004 to 23.59
35.7 to 35.70
3.0 to 3.00
9 to 9.00
Please tell me how can I do it in velocity template? I searched a lot for this and found that I can use velocity tools, but there are no examples related to it? and can i use velocity tools in templates?
Velocity tools are expected to be used in Velocity templates; essentially they are objects added to the variables available in a template so that you can use $numberTool.format("#0.00", $val) or similar. If none of the available tools don't fit your needs, simply create a POJO and add it to the template.
To make it working you also should add the following maven dependency:
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-tools</artifactId>
<version>2.0</version>
</dependency>
and write following code:
context.put("numberTool", new NumberTool());
#set($String = "abc")
$String.format("%.2f", $val)
$val has to be Double or Float in this case...
formatCurrency($value). This is good java velocity code to format a number to currency format.
Use the MathTool from the VelocityTools project.
$math.roundTo(2, $val)
Solution by just using the Java Formatters: (without additional libraries)
NumberFormat decimalFormat = new DecimalFormat("#.00");
velocityContext.put("decimalFormat", decimalFormat);
Int Number: $decimalFormat.format($obj.intNum)
And here is how the timestamp is formatted to human readable date.
DateFormat DATETIME_FORMAT = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
velocityContext.put("datetimeFormat", DATETIME_FORMAT);
Timestamp to Date: $datetimeFormat.format($obj.timestamp)
$numberTool.format("#0.00", $val)
A better way to do things besides using $numberTool.format is to use one of the MessageFormat-based tool classes that do more than just numbers. For example, we use MessageTool which is Struts-specific, but you can use something similar like ResourceTool instead:
resources.properties
some.key=The price is currently {0,number,$#.##}
template.vm
<p>
$msg.get('some.key', 'resources', [$price])
</p>
This way, you get the number in context and not just all by itself. In a non-English language, the number might be more appropriate to come to the left of the text, or in the middle, or whatever. This gives you much more flexibility than simply formatting the number all by itself.

Categories

Resources