I am attempting to use MessageFormat class to parse a message. But I get "MessageFormat parse error!". I got this code from internet. Here is the link:
package myy.test;
import java.text.MessageFormat;
import java.text.ParseException;
public class TestParse {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
// creating and initializing MessageFormat
MessageFormat mf
= new MessageFormat("{0, number, #}, {2, number, #.#}, {1, number, #.##}");
;
// creating and initializing String source
String str = "10.456, 20.325, 30.444";
System.out.println(str);
// parsing the string
// accoridng to MessageFormat
// using parse() method
Object[] hash = mf.parse(str);
// display the result
System.out.println("Parsed value are :");
for (int i = 0; i < hash.length; i++)
System.out.println(hash[i]);
}
catch (ParseException e) {
System.out.println("\nString is Null");
System.out.println("Exception thrown : " + e);
}
}
}
I get the following output in the console.
10.456, 20.325, 30.444
String is Null
Exception thrown : java.text.ParseException: MessageFormat parse error!
Why do I get this error and how do I resolve it? Thanks.
I changed the parameters in the constructor to this
MessageFormat mf = new MessageFormat("{0,number,#,###.##}, {2,number,#,###.##}, {1,number,#,###.##}");
Consolo output is like this:
10.456, 20.325, 30.444
Parsed value are :
10.456
30.444
20.325
As always when encountering parsing issues, try doing the reverse operation to see when input the parse is expecting. This is a general guideline that applies to XML, JSON, Dates, and to MessageFormat.
MessageFormat mf
= new MessageFormat("{0, number, #}, {2, number, #.#}, {1, number, #.##}");
;
System.out.println(mf.format(new Integer[] { 10456, 30444, 20325 }));
Output
10456, 20325, 30444
As you can see, the output has leading spaces. If we change to:
String str = " 10.456, 20.325, 30.444";
Then it all works.
Output
10.456, 20.325, 30.444
Parsed value are :
10.456
30.444
20.325
Related
I'm using NumberFormat in my app to get the currency formatted Strings. Like if a user inputs 12.25 in the field then it will be changed to $12.25 based on locale. Here the Locale is en-US.
Now I want to get the 12.25 value as double form the formatted string.
To do that I have used:
NumberFormat.getCurrencyInstance().parse("$12.25").doubleValue();
Above line giving me the result of 12.25 which is my requirement. But suppose a user changed his locale to something else en-UK. Now for that locale above statement is giving me parseException. Because for the locale en-UK, currency string $12.25 is not parsable.
So is there any way to get the double value from currency formatted string irrespective of what the locale is?
I don't know either the below solution is perfect or not but it is working according to my requirement.
try {
return NumberFormat.getCurrencyInstance().parse(currency).doubleValue();
} catch (ParseException e) {
e.printStackTrace();
// Currency string is not parsable
// might be different locale
String cleanString = currency.replaceAll("\\D", "");
try {
double money = Double.parseDouble(cleanString);
return money / 100;
} catch (Exception ex) {
ex.printStackTrace();
}
}
return 0;
What about
new Double(NumberFormat.getCurrencyInstance().parse("$12.25").doubleValue());
and also you could use
Double.valueOf() creates a Double object so .doubleValue() should not be necessary.
also Double.parseDouble(NumberFormat.getCurrencyInstance().parse("$12.25"));
could work
Here's a little algorithm that may help you :
public static void main(String[] args) {
String cash = "R$1,000.75"; //The loop below will work for ANY currency as long as it does not start with a digit
boolean continueLoop = true;
char[] cashArray = cash.toCharArray();
int cpt = 0;
while(continueLoop){
try
{
double d = Double.parseDouble(cashArray[cpt]+"");
continueLoop = false;
}catch(NumberFormatException nfe){
cpt += 1;
}
}
System.out.println(cpt);
//From here you can do whatever you want....
String extracted = cash.substring(cpt);
NumberFormat format = NumberFormat.getInstance(Locale.US); //YOUR REQUIREMENTS !!!! lol
try {
Number youValue = format.parse(extracted);
System.out.println(youValue.doubleValue());
} catch (ParseException ex) {
//handle your parse error here
}
}
You should get as result here in the output:
2
1000.75
I have a parser to parse the below response,the issue is i am able to parse only first table dataset not able to parse second or later table dataset,not sure where looping is going wrong.the xml response is like
anyType{schema=anyType{element=anyType{complexType=anyType{choice=anyType{element=anyType{complexType=anyType{sequence=anyType{element=anyType{}; element=anyType{}; element=anyType{}; element=anyType{}; element=anyType{}; }; }; }; }; }; }; }; diffgram=anyType{NewDataSet=anyType{Table=anyType{RemMessage=Exeed Discount Limit on Invoice dated on 05/03/2015 for C SHAH , from 3 - Lokhandwala Showroom; InvM_Id=77693; DocType=3; PrmR_TypeId=3; PrmR_Id=1820; }; **Table=anyType{RemMessage=Exeed Discount Limit on Invoice dated on 14/03/2015 for G P SHAH , from 3 - Khar Showroom; InvM_Id=77800; DocType=3; PrmR_TypeId=3; PrmR_Id=1865; };** Table=anyType{RemMessage=Exeed Discount Limit on Invoice dated on 14/03/2015 for DOONGARSHI SHAH , from 3 - Khar Showroom; InvM_Id=77801; DocType=3; PrmR_TypeId=3; PrmR_Id=1866; }; }; }; }
my parsing code is not parsing entire response properly,The code is
public class KSoap2ResultParser {
public static void parseBusinessObject(String input, Object output) throws NumberFormatException, IllegalArgumentException, IllegalAccessException, InstantiationException{
System.out.println("input----> " +input);
Class theClass = output.getClass();
Field[] fields = theClass.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Type type=fields[i].getType();
System.out.println("type--" +type);
fields[i].setAccessible(true);
//detect String
if (fields[i].getType().equals(String.class)) {
String tag = fields[i].getName() + "="; //"s" is for String in the above soap response example + field name for example Name = "sName"
System.out.println("fff------------"+tag);
if(input.contains(tag)){
String strValue = input.substring(input.indexOf(tag)+tag.length(), input.indexOf(";", input.indexOf(tag)));
System.out.println("RemMessage------------"+strValue);
if(strValue.length()!=0){
fields[i].set(output, strValue);
}
}
}
//detect int or Integer
if (type.equals(Integer.TYPE) || type.equals(Integer.class)) {
String tag = fields[i].getName() + "="; //"i" is for Integer or int in the above soap response example+ field name for example Goals = "iGoals"
if(input.contains(tag)){
String strValue = input.substring(input.indexOf(tag)+tag.length(), input.indexOf(";", input.indexOf(tag)));
System.out.println("strvalue------------"+strValue);
if(strValue.length()!=0){
fields[i].setInt(output, Integer.valueOf(strValue));
}
}
}
//detect float or Float
if (type.equals(Float.TYPE) || type.equals(Float.class)) {
String tag = "f" + fields[i].getName() + "=";
if(input.contains(tag)){
String strValue = input.substring(input.indexOf(tag)+tag.length(), input.indexOf(";", input.indexOf(tag)));
if(strValue.length()!=0){
fields[i].setFloat(output, Float.valueOf(strValue));
}
}
}
}
}
}
and i am calling from
String response=androidHttpTransport.responseDump;
SoapObject obj=(SoapObject)envelope.getResponse();
for(int i=0; i < obj.getPropertyCount(); i++) {
GetReminder rem = new GetReminder();
KSoap2ResultParser.parseBusinessObject(obj.getProperty(i).toString(),rem);
reminders.add(rem);
}
there is an issue in parsing please help me to correct it.
First, FYI, the response you get is not XML.
You have 2 solutions to properly parse the response:
1- Get the WS response as an actual XML
To do that see this thread. And then use a proper XML DOM parser to process the response and build the Java objects.
2- Do it directly with a SOAP api
Looking for the best way, I came across this with tips that are relevant to your problem.
Look at parsing array elements. In your case, you can change your code:
Change the line:
KSoap2ResultParser.parseBusinessObject(obj.getProperty(i).toString(),rem);
by:
KSoap2ResultParser.parseBusinessObject((SoapObject)obj.getProperty(i),rem);
And change the signature of method parseBusinessObject(SoapObject pojoSoap, Object obj). Then in the method, for each type, e.g. for String:
if(strValue.length()!=0){
fields[i].set(output, strValue);
}
by:
if(strValue.length()!=0){
String fieldName = fields[i].getName();
String fieldValue = pojoSoap.getProperty(fieldName).toString();
fields[i].set(output, fieldValue);
}
Trying to figure out why the following code is not outputting expecting results. Please advise. Thank you.
import java.text.*;
public class Test {
public static void main(String[] args) {
String s = "987.123456";
double d = 987.123456d;
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(5);
System.out.println(nf.format(d) + " ");
try {
System.out.println(nf.parse(s));
} catch (Exception e) {
System.out.println("got exc");
}
}
}
Output:
987.12346 // Expected 987.12345 not 987.12346
987.123456
Your second print doesn't format the double you've parsed.
// System.out.println(nf.parse(s));
System.out.println(nf.format(nf.parse(s))); // <-- 987.12346
To get the output you asked for, you can add a call to NumberFormat#setRoundingMode(RoundingMode) - something like
nf.setMaximumFractionDigits(5);
nf.setRoundingMode(RoundingMode.DOWN);
When I run the following code I would expect a stacktrace, but instead it looks like it ignores the faulty part of my value, why does this happen?
package test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test {
public static void main(final String[] args) {
final String format = "dd-MM-yyyy";
final String value = "07-02-201f";
Date date = null;
final SimpleDateFormat df = new SimpleDateFormat(format);
try {
df.setLenient(false);
date = df.parse(value.toString());
} catch (final ParseException e) {
e.printStackTrace();
}
System.out.println(df.format(date));
}
}
The output is:
07-02-0201
The documentation of DateFormat.parse (which is inherited by SimpleDateFormat) says:
The method may not use the entire text of the given string.
final String value = "07-02-201f";
In your case (201f) it was able to parse the valid string till 201, that's why its not giving you any errors.
The "Throws" section of the same method has defined as below:
ParseException - if the beginning of the specified string cannot be parsed
So if you try changing your string to
final String value = "07-02-f201";
you will get the parse exception, since the beginning of the specified string cannot be parsed.
You can look whether the entire string was parsed as follows.
ParsePosition position = new ParsePosition(0);
date = df.parse(value, position);
if (position.getIndex() != value.length()) {
throw new ParseException("Remainder not parsed: "
+ value.substring(position.getIndex()));
}
Furthermore when an exception was thrown by parse the position will also yield getErrorIndex().
Confirmed... I also found that "07-02-201", "07-02-2012 is the date" compiles. However, "bar07-02-2011" does not.
From the code in SimpleDateFormat, it seems like the parsing terminates the moment an illegal character is found that breaks the matching. However, if the String that has already been parsed up to that point is valid, it is accepted.
public class Reader {
public static void main(String[] args) throws IOException, ParseException {
BufferedReader reader;
String animalName="cat";
String animal = null;
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream("C:/dila.txt")));
Map<String, Integer> result = new LinkedHashMap<String, Integer>();
Map<String, Integer> result2 = new LinkedHashMap<String, Integer>();
while (reader.ready()) {
String line = reader.readLine();
/split a line with spaces/
String[] values = line.split(",");
String key = null;
if(values[1].compareTo(animalName)==0){
key = values[0];
animal=""+values[1].compareTo(animalName);
int sum = 0;
int count = 0;
/get a last counter and sum/
if (result.containsKey(key)) {
sum = result.get(key);
count = result2.get(key);
} else{
}
/increment sum a count and save in the map with key/
result.put(key, sum + Integer.parseInt(values[2]));
result2.put(key, count + 1);
}
}
/interate and print new output/
for (String key : result.keySet()) {
Integer sum = result.get(key);
Integer count = result2.get(key);
System.out.println(key +" "+animalName+ " " + sum + "\t" + count);
}
reader.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
i have below text file
11/2/2010,cat,6
11/2/2010,cat,3
11/2/2010,dog,4
11/2/2010,cat,11
11/3/2010,cat,1
11/3/2010,dog,3
11/3/2010,cat,8
11/3/2010,cat,80
in my java code it is filtered below output.
11/2/2010 cat 20 3
11/3/2010 cat 104 4
11/4/2010 cat 26 2
But i want below mention result.
11/01/2010
11/02/2010 cat 20 3
11/03/2010 cat 104 4
11/04/2010 cat 26 2
11/05/2010
11/06/2010
11/07/2010
11/08/2010
11/09/2010
11/10/2010
11/11/2010
11/12/2010
11/13/2010
11/14/2010
11/15/2010
11/16/2010
11/17/2010
11/18/2010
11/19/2010
11/20/2010
11/21/2010
11/22/2010
11/23/2010
11/24/2010
11/25/2010
11/26/2010
11/27/2010
11/28/2010
11/29/2010
11/30/2010
Above shows my java code...(i am new for this site thats why my question is little bit unclear to you. now i got the method. Now i again post my question. So please read this and give me the solution....)
Do this:
read the first line of txt file to get the month.
create a hashmap of size of the month. Populate it with java.util.date from 1st to the last of the dates in that month. Date as key and null as value.
read the text file, get the first of CSV in each line convert it to Date object
Do a lookup in Hashmap and insert the fomatted String as the value to corresponding date key. You can use Formatter for padding.
repeat #3 and #4 till EOF
Now, iterate in Hashmap and print out. For all the NULL values just print formatted Key (which is date)
Hope this helps.
1. use SimpleDateFormat to convert date String to date object
2. write a method that takes this date and returns maximum days in that month using java.util.Calendar.getMaximum
3. create a hashMap with Keys as Dates in that month and values as Null
4. now, read line by line and user SimpleDateFormat to convert first of CSV into date. Use this date as key and put the printable String as value.
5. Iterate throught this hashmap.keys() and to get the values one by one. If the value is null just print the key i.e. date.
:)
Can't help more.
Hope this method helps you in filling the keys.
public static String[] getDates(String date)
{
String[] dates=null;
SimpleDateFormat sdf=new SimpleDateFormat("MM/dd/yyyy");
try {
Date d=sdf.parse(date);
Calendar cal=GregorianCalendar.getInstance();
cal.setTime(d);
int month=cal.get(Calendar.MONTH);
int year=cal.get(Calendar.YEAR);
int startDate=cal.getActualMinimum(Calendar.DAY_OF_MONTH);
int endDate=cal.getActualMaximum(Calendar.DAY_OF_MONTH);
StringBuilder sb=new StringBuilder();
dates=new String[endDate];
for(int i=startDate;i<=endDate;i++)
{
sb=new StringBuilder();
sb.append(month+1);
sb.append("/");
sb.append(i);
sb.append("/");
sb.append(year);
dates[i-1]=sb.toString();
}
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return dates;
}