Getting "parse exception" - java

I want to change the string into the date formate for that I am using SimpleDateFormat class. I am passing the string as String+Integer.toString(int) from list of strings and SimpleDateFormat pattern as an inputs.
Note: Instead of String+Integer.toString(int) if I pass actual string like "Jan 09 2019" successfully convert string into the date. I tried a lot with different things.
dateList is a list of "MMM dd" formate dates.
Adding year on that formate by doing dateList.get(5)+Integer.toString(year) which is giving me parse exception <<-- Instead of this if I hardcode the date like Jan 09 2019 converting string into the date.
finalDatesInMMMDDYYYYFormat is another list where I am saving the dates in MMM dd yyyy format.
Utils.parseDate is a method I wrote in Utils class where I mentioned try-catch block.
int year = 2019;
private List<String> dateList = new ArrayList<>();
private List<Date> finalDatesInMMMDDYYYYFormat = new ArrayList<>();
final String testString = dateList.get(5)+Integer.toString(year);
finalDatesInMMMDDYYYYFormat.add(Utils.parseDate(testString, new SimpleDateFormat("MMM dd yyyy")));
Expected: Change the string into the date and add it to finalDatesInMMMDDYYYYFormat
Actual: Getting parse exception.

java.time
int year = 2019;
DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("MMM dd")
.toFormatter(Locale.ENGLISH);
List<LocalDate> finalDatesWithoutFormat = new ArrayList<>();
String dateString = "JAN 09";
MonthDay md = MonthDay.parse(dateString, dateFormatter);
finalDatesWithoutFormat.add(md.atYear(year));
System.out.println(finalDatesWithoutFormat);
The output from this snippet is:
[2019-01-09]
java.time, the modern Java date and time API, includes a class for a date without year, MonthDay, which may serve your purpose better than an ordinary date. My code also shows how to supply a year to obtain a LocalDate (a date without time of day).
I recommend you don’t use Date and SimpleDateFormat. Those classes are poorly designed and long outdated, the latter in particular notoriously troublesome.
What went wrong in your code?
From the information you have provided it’s not possible to tell why your code didn’t work. Possible explanations include the following, but there might be others.
As rockfarkas said in another answer, when concatenating your strings you were not putting any space between day of month and year, but the format string you used for parsing required a space there.
If your month abbreviations are in English, for example, and your JVM’s default locale is not English, parsing will fail (except in the rare cases where the month abbreviation coincides). You should always give your formatter a locale to specify the language used in the string to be parsed (or produced).
As an aside, your variable name finalDatesInMMMDDYYYYFormat was misleading since a Date hasn’t got (cannot have) a format.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Another example of wrong locale causing date parsing to fail: Java - Unparseable date

If you want parse format "MMM dd yyyy", you should add an extra space to your test string like this:
final String testString = dateList.get(5) + ' ' + year;

Related

How to resolve Unparseable date Exception in Java 8 with Date format yyyy-MM-dd hh:mm a

I have a text file from which I am reading and setting transaction POJO class data, to get the difference between start and end time I need to parse the time information in date object.
DateFormat format = new SimpleDateFormat(dateFormat);
System.out.println("Date format in play:"+dateFormat);
Transaction transaction = storageRepositroy.getTransaction(key);
Date start = format.parse(transaction.getStartDate() + " " + transaction.getStartTime());//line no. 29
Date end = format.parse(transaction.getEndDate() + " " + transaction.getEndTime());
I am getting exception while running this code
Exception is
Date format in play:yyyy-MM-dd hh:mm a
java.text.ParseException: Unparseable date: "2020–03–01 03:15 PM"
at java.text.DateFormat.parse(DateFormat.java:366)
at dc.tech.transaction.util.TimeUtil.calculateAverageTime(TimeUtil.java:29)
yyyy-MM-dd hh:mm a is the date format which I am passing to SimleDateFormat constructor. I am unable to understand and debug why I am getting this error.
java.time
I recommend that you use java.time, the modern Java date and time API, for your date and time work.
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuu\u2013MM\u2013dd");
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH);
String dateString = "2020–03–01";
String timeString = "03:15 PM";
LocalDate date = LocalDate.parse(dateString, dateFormatter);
LocalTime time = LocalTime.parse(timeString, timeFormatter);
LocalDateTime dateTime = date.atTime(time);
System.out.println(dateTime);
Output:
2020-03-01T15:15
With java.time it is straightforward to combine date and time after parsing, so I prefer to parse them individually.
What went wrong in your code?
Credits go to Ajeetkumar for noticing and reporting in comments: The hyphen in your date string is not a usual minus sign or hyphen with character value 2D hexadecimal (45 decimal), but a en dash with character value 2013 hexadecimal (8211 decimal). So when you specify a usual hyphen in your format pattern string, they don’t match, and parsing fails. Instead I am using a Unicode escape for putting the en dash into the format pattern string. Simply pasting it in there would have worked too (provided that you save your .java file with a character encoding that supports it), but I wanted to make the reader aware that something special was going on here, so I preferred the Unicode escape with \u.
There is another problem with your code: You are not providing any locale for your formatter. So it uses the default locale of your JVM. As long as that locale expects PM, parsing will work. If one day you change your locale setting or run your code on a computer or JVM with a different default locale, parsing will suddenly fail, at you may have a hard time figuring out why. I have specified English locale for parsing the time. Some would prefer doing it for the date too even though technically it isn’t necessary.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Unicode Character 'EN DASH' (U+2013) on FileFormat.info.
I always stick to this mantra: use exactly the same format as your date-time string.
In the solutions given below, I have copied your date-time string into the pattern that I've specified for SimpleDateFormat and DateTimeFormatter and replaced the numbers with the corresponding letters e.g. 2020 with yyyy while keeping the rest of things (symbols, space etc.) intact.
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
DateFormat sdf = new SimpleDateFormat("yyyy–MM–dd hh:mm a", Locale.ENGLISH);// Make sure to use Locale
String dateTimeString = "2020–03–01 03:15 PM";// The string copied from the exception you have got
Date date = sdf.parse(dateTimeString);
System.out.println(sdf.format(date));
}
}
Output:
2020–03–01 03:15 PM
Note: The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. I suggest you should stop using them completely and switch to the modern date-time API.
Using the modern date-time API:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy–MM–dd hh:mm a", Locale.ENGLISH);// Make sure to use Locale
String dateTimeString = "2020–03–01 03:15 PM";// The string copied from the exception you have got
System.out.println(LocalDateTime.parse(dateTimeString, dtf));
}
}
Output:
2020-03-01T15:15
Learn more about the modern date-time API at Trail: Date Time.
If you are doing it for your Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

I try to convert a String to Date format in java but has an exception

I try to convert String to Date format but I got an exception!
Here is my code:
SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yyyy");
startDate = format.parse(startDateString);
it should convert "14-MAY-2004" to Date. Thanks.
java.time
I recommend that you use java.time, the modern Java date and time API, for your date work.
DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("d-MMM-uuuu")
.toFormatter(Locale.ENGLISH);
String startDateString = "14-MAY-2004";
LocalDate startDate = LocalDate.parse(startDateString, dateFormatter);
System.out.println(startDate);
Output is:
2004-05-14
Only if you indispensably need a Date object for a legacy API not yet upgraded to java.time, convert:
Instant startOfDay = startDate.atStartOfDay(ZoneId.systemDefault()).toInstant();
Date oldfashionedDate = Date.from(startOfDay);
System.out.println(oldfashionedDate);
Output in my time zone:
Fri May 14 00:00:00 CEST 2004
What went wrong in your code?
It’s almost certainly a locale problem. You didn’t specify a locale and hence no language for the month name or abbreviation. Always do that when the date string includes text in some language. Your SimpleDateFormat was using the default formatting locale of your JVM, and if that was a non-English-speaking locale, parsing was deemed to fail with an exception as you mentioned.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Similar question: Java - Unparseable date
From the statment "it should convert 14-MAY-2004 to date" i assume your input string is 14-MAY-2004 and you want this string to be converted to Date
String js="14-May-2004";
Date dt=new Date(js);
LocalDateTime localDateTime=dt.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
localDateTime.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"));//or in the same format use- "dd-MMM-yyyy"

Parsing from SimpleDateFormat to Date not working?

SimpleDateFormat df = new SimpleDateFormat();
Date lastLogin = null;
try {
String troubleChild = lineScanner.next();
lastLogin = df.parse(troubleChild);
} catch (ParseException e) {
System.out.println("ohnoes");
}
Hi I'm quite new to using the date functions and I've come up with a problem. I have a file that is being parsed into various variables and they all work except this one i can never get it so that it passes the try/catch clause i've looked up similar problems but none of them work on my code.(The date i am inputting is in the format: Mon, Oct 30 22:20:11 GMT 2017) please can I get some help and thanks for it!
Solution: java.time
Please don’t take the trouble with the long outmoded classes Date and SimpleDateFormat. Instead use java.time, the modern Java date and time API also known as JSR-310:
DateTimeFormatter dtf
= DateTimeFormatter.ofPattern("E, MMM d H:mm:ss z uuuu", Locale.UK);
String inputDate = "Mon, Oct 30 22:20:11 GMT 2017";
ZonedDateTime lastLogin = ZonedDateTime.parse(inputDate, dtf);
System.out.println(lastLogin);
This prints
2017-10-30T22:20:11Z[GMT]
Since dates and times may come in so many different textual formats, I am using a format pattern string to specify your particular format. For which letters you may use, and what difference it makes whether you use 1, 3 or 4 of the same letter, see the documentation. Beware that format pattern strings are case sensitive.
Problem: SimpleDateFormat
You used the no-arg SimpleDateFormat constructor. The way I read the documentation, this gives you the default date format for your locale. If your JVM is running UK locale, I believe the format goes like 28/11/17 10:57 — not much like the input format you were trying to parse. You can use System.out.println(df.format(new Date())); to find out. The usual SimpleDateFormat constructor to use would be SimpleDateFormat(String, Locale) so that you may again supply a format pattern string and a locale.

convert String to date using java 8 and format -> 'uuuu-MM-dd'

I want to convert from string to date using Java 8.
I can easily convert using SimpleDateFormat and yyyy-MM-dd format
String startDate2="2017-03-24";
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(new java.sql.Date(sdf1.parse(startDate2).getTime()));
output:
2017-03-24
String startDate2="2017-03-24";
SimpleDateFormat sdf1 = new SimpleDateFormat("uuuu-MM-dd");
System.out.println(new java.sql.Date(sdf1.parse(startDate2).getTime()));
But when I use 'uuuu-MM-dd' instead of 'yyyy-MM-dd'
output :
1970-03-24(wrong)
now in Java 8:
String startDate1="2017-03-23";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd");
But I don't know how I can get the date which would be sql date type same as above correct output.
java.sql.Date has a static valueOf method that takes a Java 8 LocalDate so you can do:
String startDate1 = "2017-03-23";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd");
LocalDate date = LocalDate.parse(startDate1, formatter);
java.sql.Date sqlDate = java.sql.Date.valueOf(date);
As far as I can see, you have a text in yyyy-MM-dd format and you want it in uuuu-MM-dd format. So you need two formats:
String startDate2="2017-03-24";
SimpleDateFormat sourceFormat = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat targetFormat = new SimpleDateFormat("uuuu-MM-dd");
java.sql.Date date = new java.sql.Date(sourceFormat.parse(startDate2).getTime());
String formattedAsDayOfWeek = targetFormat.format(date);
System.out.println(formattedAsDayOfWeek);
Bottom line is that Date contains a millisecond value. java.sql.Date.toString() uses the yyyy-MM-dd format regardless how you parsed it. java.util.sql.Date uses another format: EEE MMM dd hh:mm:ss zzz yyyy with English Locale.
You can do other formatting with DateFormat -s.
I presume you need the uuuu-MM-dd format for inserting data to the database. What does that logic look like?
You don’t want a java.sql.Date. You want a LocalDate. Your SQL database wants one too.
String startDate2 = "2017-03-24";
LocalDate date = LocalDate.parse(startDate2);
System.out.println(date);
Output is:
2017-03-24
I am exploiting the fact that your string is in ISO 8601 format. The classes of java.time including LocalDate parse this format as their default, that is, without any explicit formatter.
You also note that we don’t need any explicit formatter for formatting back into uuuu-MM-dd format for the output. The toString method implicitly called from System..out.println() produces ISO 8601 format back.
Assuming that you are using a JDBC 4.2 compliant driver (I think we all are now), I am taking the way to pass it on to your SQL database from this question: Insert & fetch java.time.LocalDate objects to/from an SQL database such as H2:
myPreparedStatement.setObject ( 1 , date ); // Automatic detection and conversion of data type.
Refer to the linked question for much more detail.
The java.sql.Date class is poorly designed, a true hack on top of the already poorly designed java.util.Date class. Both classes are long outdated. Don’t use any of them anymore.
One more link: Wikipedia article: ISO 8601

How to parse month full form string using DateFormat in Java?

I tried this:
DateFormat fmt = new SimpleDateFormat("MMMM dd, yyyy");
Date d = fmt.parse("June 27, 2007");
error:
Exception in thread "main" java.text.ParseException: Unparseable date: "June 27, 2007"
The java docs say I should use four characters to match the full form.
I'm only able to use MMM successfully with abbreviated months like "Jun" but i need to match full form.
Text: For formatting, if the number
of pattern letters is 4 or more, the
full form is used; otherwise a short
or abbreviated form is used if
available. For parsing, both forms are
accepted, independent of the number of
pattern letters.
https://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html
You are probably using a locale where the month names are not "January", "February", etc. but some other words in your local language.
Try specifying the locale you wish to use, for example Locale.US:
DateFormat fmt = new SimpleDateFormat("MMMM dd, yyyy", Locale.US);
Date d = fmt.parse("June 27, 2007");
Also, you have an extra space in the date string, but actually this has no effect on the result. It works either way.
LocalDate from java.time
Use LocalDate from java.time, the modern Java date and time API, for a date
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MMMM d, u", Locale.ENGLISH);
LocalDate date = LocalDate.parse("June 27, 2007", dateFormatter);
System.out.println(date);
Output:
2007-06-27
As others have said already, remember to specify an English-speaking locale when your string is in English. A LocalDate is a date without time of day, so a lot better suitable for the date from your string than the old Date class. Despite its name a Date does not represent a date but a point in time that falls on at least two different dates in different time zones of the world.
Only if you need an old-fashioned Date for an API that you cannot afford to upgrade to java.time just now, convert like this:
Instant startOfDay = date.atStartOfDay(ZoneId.systemDefault()).toInstant();
Date oldfashionedDate = Date.from(startOfDay);
System.out.println(oldfashionedDate);
Output in my time zone:
Wed Jun 27 00:00:00 CEST 2007
Link
Oracle tutorial: Date Time explaining how to use java.time.
Just to top this up to the new Java 8 API:
DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("MMMM dd, yyyy").toFormatter();
TemporalAccessor ta = formatter.parse("June 27, 2007");
Instant instant = LocalDate.from(ta).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
Date d = Date.from(instant);
assertThat(d.getYear(), is(107));
assertThat(d.getMonth(), is(5));
A bit more verbose but you also see that the methods of Date used are deprecated ;-) Time to move on.
val currentTime = Calendar.getInstance().time
SimpleDateFormat("MMMM", Locale.getDefault()).format(date.time)

Categories