Unparsable date exception - java

I'm currently working on some simple project in Java and I have date in the following string:
String dateString = "Sun 7/14 03:44 AM 2013";
and want to to convert this string to Date object. I'm using following lines of code to do that. I searched site and found solution how to do this with DateFormatter:
DateFormat format = new SimpleDateFormat("EEE M/dd hh:mm a yyyy");
Date d = format.parse(dateString);
But I'm probably doing something wrong, because I always get exception:
Unparseable date: "Sun 7/14 03:44 AM 2013"
This seems to be problem with pattern I'm using but tried different patterns and nothing work.

Certain fields such as the day of week fields and/or AM/PM marker may not match those from your default Locale. ParseException has the method getErrorOffset to determine exactly where the pattern does not match.
try
DateFormat format =
new SimpleDateFormat("EEE M/dd hh:mm a yyyy", Locale.ENGLISH);

It is important to add Locale as you are parsing language day of week names.
String dateString = "Sun 7/14 03:44 AM 2013";
DateFormat format = new SimpleDateFormat("EEE M/dd hh:mm a yyyy", Locale.US);
Date d = format.parse(dateString);

I tried this out and the following worked,
String stringDate = "Sun 7/14 03:44 AM 2013";
DateFormat format = new SimpleDateFormat("EEE MM/dd hh:mm a yyyy");
System.out.println("Parsed Date = "+format.parse(stringDate));
The output was as follows
Parsed Date = Sun Jul 14 03:44:00 BST 2013

SimpleDateFormat formatter = new SimpleDateFormat("/* type your own format*/");
String formattedDate = formatter.format(todaysDate);
System.out.println("Formatted date is ==>"+formattedDate);
try this code

The modern answer for the sake of completeness. While the other answers were good answers in 2013, Date, DateFormat and SimpleDateFormat are now long outdated, and I recommend you replace them with their modern counterparts:
DateTimeFormatter parser
= DateTimeFormatter.ofPattern("EEE M/dd hh:mm a yyyy", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(dateString, parser);
The result is a LocalDateTime of 2013-07-14T03:44 as expected.
The format pattern string is still the same, and the need for an English language locale is the same.

Related

Java Date TIME Format AM/PM Configuration

I am facing problems some while formatting the date:
Date : 11/06/2020 04:14:20
Date Format:dd/MM/yyyy hh:mm:ss a
Exception:
java.text.ParseException: Unparseable date: "11/06/2020 04:14:20"
Following is the code
Blockquote
public String getFormatDate(String inputDate) {
String strDate = "";
try {
DateFormat outputFormat = new SimpleDateFormat("MMMM dd, yyyy hh:mm:ss a");
DateFormat inputFormat = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss a");
Date date1 = inputFormat.parse(inputDate);
strDate = outputFormat.format(date1);
}catch( Exception exe) {
exe.printStackTrace();
logger.error( "[ERROR] getFormatDate:. ", exe );
}
return strDate;
}
Blockquote
Any help would be greatly appeciated.
You can check this code you have to pass the am/pm part too with the date string value as your format is expecting that.
//String date = "11/06/2020 04:14:20";
String date = "11/06/2020 04:14:20 am";
DateFormat df = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss a");
https://ideone.com/3nibwJ
Use proper date-time objects for your dates and times
For the vast majority of purposes you should not keep your date and time in a string and should not convert your date and time from a string in one format to a string in another format. Keep your date and time in a ZonedDateTime or LocalDateTime object.
When you are required to accept string input, parse that input into a date-time object immediately. I am using and recommending java.time, the modern Java date and time API:
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("dd/MM/uuuu HH:mm:ss");
String input = "11/06/2020 04:14:20";
LocalDateTime dateTime = LocalDateTime.parse(input, inputFormatter);
System.out.println(dateTime);
Output so far is:
2020-06-11T04:14:20
Since there is no AM or PM in your string, I have assumed that 04:14:20 was the time of day from 00:00:00 through 23:59:59. If you intended otherwise, you need to explain how.
Only when you need to give string output, format your date and time back into a string of appropriate format:
DateTimeFormatter outputFormatter = DateTimeFormatter
.ofPattern("MMMM dd, yyyy hh:mm:ss a", Locale.ENGLISH);
String output = dateTime.format(outputFormatter);
System.out.println(output);
June 11, 2020 04:14:20 AM
Do provide a locale for the formatter so Java knows which language to use for the month name and the AM/PM indicator.
What went wrong in your code?
Your string has no AM nor PM: 11/06/2020 04:14:20. Yet your format pattern string requires an AM/PM marker in the end. This is what format pattern letter a signifies. So your string wasn’t in the format that you required. This was the reason for the exception that you observed.
Link
Oracle tutorial: Date Time explaining how to use java.time.
Thanks All for your help:
I have changed the source date "11/06/2020 04:14:20" to "06/11/2020 04:14:20 PM", and then after perform follwoing steps, its working for me:
Blockquote
DateFormat inputFormat = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss a");
inputFormat.setTimeZone( TimeZone.getTimeZone("UTC") );
Date dDate = inputFormat.parse( srcDate );
String strDeDate = formatDateToString( dDate, "dd/MM/yyyy hh:mm:ss a", "IST" );
public String formatDateToString(Date date, String format,String timeZone) {
if (date == null) return null;
SimpleDateFormat sdf = new SimpleDateFormat(format);
if (timeZone == null || "".equalsIgnoreCase(timeZone.trim())) {
timeZone = Calendar.getInstance().getTimeZone().getID();
}
sdf.setTimeZone(TimeZone.getTimeZone(timeZone));
return sdf.format(date);
}
Blockquote

How to find a Future Date in Java(say two months from today) in 24 February 2019 format

Below is the approach I am going with :
Date DateObject = new Date();
SimpleDateFormat formatDate = new SimpleDateFormat("dd MMMM yyyy");
String dateString = formatDate.format(DateObject);
System.out.println(dateString);
Now this gives me the current date in desired format. I want to find the Value of Date in same format exactly two months from this date.
I also tried to work with below approach :
LocalDate futureDate = LocalDate.now().plusMonths(2);
This gives me the date I want which is two months from now but in 2019-04-24 format. When I tried to format this date using SimpleDateFormat it is giving me Illegal Argument Exception.
Try using the DateTimeFormatter class introduced in Java 8, avoid using the SimpleDateFormat :
public static void main(String[] args) {
LocalDate futureDate = LocalDate.now().plusMonths(2);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMMM yyyy");
String dateStr = futureDate.format(formatter);
System.out.println(dateStr);
}
Output:
24 April 2019
The DateTimeFormatter in Java 8 is immutable and thread-safe alternative to SimpleDateFormat.

Using SimpleDateFormat to format a string parse exception? [duplicate]

This question already has answers here:
String to Date Conversion mm/dd/yy to YYYY-MM-DD in java [duplicate]
(5 answers)
Closed 4 years ago.
I have a date object that returns the below string value in doing date.toString()
String date = "Wed Jun 27 12:33:00 CDT 2018";
And I want to format it in exactly this style:
"June-27-2018 5:33:00 PM GMT".
I tried using SimpleDateFormat
protected SimpleDateFormat dateFormat = new SimpleDateFormat( "MMMM-dd-yyyy h:mm:ss a z", Locale.US);
But I keep getting a parse exception. Is there any way to format this the way I need it to? The timezone needs to be converted too.
First, you shouldn’t have a Date object. The Date class is long outdated (no pun intended). Today you should prefer to use java.time, the modern and much nicer date and time API. However, I am assuming that you are getting a Date from some legacy API that you cannot change. The first thing you should do is convert it to an Instant. Instant is the corresponding class in java.time. Then you should do any further operations from there.
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("MMMM-dd-yyyy h:mm:ss a z", Locale.US);
ZoneId desireedZone = ZoneId.of("Etc/GMT");
Date yourOldfashionedDate = // …;
ZonedDateTime dateTimeInGmt = yourOldfashionedDate.toInstant().atZone(desireedZone);
String formattedDateTime = dateTimeInGmt.format(formatter);
System.out.println(formattedDateTime);
This snippet prints the desired:
June-27-2018 5:33:00 PM GMT
Converting directly from the Date object is safer and easier than converting from its string representation. The biggest problem with the latter is that the string contains CDT as time zone, which is ambiguous. It may stand for Australian Central Daylight Time, North American Central Daylight Time, Cuba Daylight Time or Chatham Daylight Time. You cannot be sure which one Java is giving you. Never rely on three and four letter time zone abbreviations if there is any way you can avoid it.
Link: Oracle tutorial: Date Time explaining how to use java.time.
Your date string cannot parse to the format you have given, so change the format to EEE MMM dd HH:mm:ss zzz yyyy
String myDate = "Wed Jun 27 12:33:00 CDT 2018";
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
SimpleDateFormat dateFormat_2 = new SimpleDateFormat("MMMM-dd-yyyy h:mm:ss a z", Locale.US);
dateFormat_2.setTimeZone(TimeZone.getTimeZone("GMT"));
Date d = dateFormat.parse(myDate);
dateFormat_2.format(d);
System.out.println(dateFormat_2.format(d));
Output :
June-27-2018 12:33:00 PM GMT
You will achieve your desired output if you pass date or object to format function.
SimpleDateFormat dateFormat = new SimpleDateFormat( "MMMM-dd-yyyy h:mm:ss a z", Locale.US);
String ans=dateFormat.format(param);
In above code param must be date or object so first convert string to date and then apply format function to get your desired output.
See below Sample code
SimpleDateFormat dateFormat = new SimpleDateFormat( "MMMM-dd-yyyy h:mm:ss a z", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
String ans=dateFormat.format(new Date());
Sample output:
June-27-2018 6:22:35 PM GMT

Difference between hh:mm a and HH:mm a

Here is my original code-
String dateString = "23 Dec 2015 1:4 PM";
Locale locale = new Locale("en_US");
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm a");
DateFormat df = new SimpleDateFormat("dd MMM yyyy HH:mm a", locale);
Date date = null;
try {
date = formatter.parse(dateString);
} catch (ParseException e) {
LOGGER.error(e);
}
String newDate = df.format(date);
System.out.println("oldDate = " + dateString);
System.out.println("newDate = " + newDate);
and here is my output-
oldDate = 23 Dec 2015 1:4 PM
newDate = 23 Dec 2015 01:04 AM
There is AM-PM difference between the oldDate and newDate. Now I changed the DateFormat code to-
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy hh:mm a");
DateFormat df = new SimpleDateFormat("dd MMM yyyy hh:mm a", locale);
and I get the expected output, which is-
oldDate = 23 Dec 2015 1:4 PM
newDate = 23 Dec 2015 01:04 PM
I'm aware that HH signifies the 24 hour format and hh signifies the 12-hour format.
My question is
If I use HH:mm a instead of hh:mm a, shouldn't this be returning the time in 24-hour format?
(or)
If it defaults to 12-hour format, shouldn't it return respective AM/PM marker depending on the date input provided?
This is just for my understanding.
Updated Answer
Here the problem is with Program flow
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm a");
this simple date formatter is used to format the date string the Date object is created, here is the important part of answer
As you are using HH instead of hh, the SimpleDateFormater considers that provided date string is in 24-Hour Format and simply ignores the AM/PM marker here.
The Date Object from constructed from this SimpleDateFormatter is passed to the
DateFormat df = new SimpleDateFormat("dd MMM yyyy HH:mm a", locale);
That's why it's printing
newDate = 23 Dec 2015 01:04 AM
if you change the line
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm a");
with
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy hh:mm a");
Everything will go smooth as it should!
Note : when creating a locale you should pass the language code to the Locale() constructor. en-us not en_us.
IMP : Code is tested on Java 8 also. Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Difference between hh:mm and HH:mm:
HH:mm => will look like 00:12, 23:00... this has 24 hour format.
hh:mm => will look like 01:00Am, 02:00Am,...01:00pm this has 12 hour format.
And the a in hh:mm a or in HH:mm a is Am/pm marker for more info go to link
A simple test is the best answer to how the pattern "HH:mm a" is interpreted. First let us investigate the printing mode:
The old format engine SimpleDateFormat:
Calendar cal = new GregorianCalendar(2015, 3, 1, 17, 45);
SimpleDateFormat sf = new SimpleDateFormat("HH:mm a", Locale.US);
System.out.println(sf.format(cal.getTime())); // 17:45 PM
Java-8 (with the new package java.time.format):
LocalTime time = LocalTime.of(17, 59);
DateTimeFormatter tf = DateTimeFormatter.ofPattern("HH:mm a", Locale.US);
System.out.println(tf.format(time)); // 17:59 PM
Here we don't observe any override in both cases. I prefer that approach because using the combination of "HH" and "a" is in my opinion rather an indication for a programming error (the user has obviously not thought enough about the meaning and official description of those pattern symbols).
Now let us investigate the parsing mode (and we will use strict mode to observe what is really going behind the scene):
String dateString = "23 Dec 2015 1:4 PM";
SimpleDateFormat df = new SimpleDateFormat("dd MMM yyyy H:m a", Locale.US);
df.setLenient(false);
Date date = df.parse(dateString);
// java.text.ParseException: Unparseable date: "23 Dec 2015 1:4 PM"
How is the behaviour in Java-8? It is the same but with a clearer error message:
DateTimeFormatter tf = DateTimeFormatter.ofPattern("H:m a", Locale.US);
tf = tf.withResolverStyle(ResolverStyle.STRICT);
LocalTime.parse("1:4 PM", tf);
// DateTimeException: Cross check failed: AmPmOfDay 0 vs AmPmOfDay 1
This message tells us that the parsed hour (in 24-hour format!) with value "1" indicates AM while the text input contains the other parsed AM/PM-value "PM". This ambivalence cannot be resolved.
Lesson: We have to be careful with lenient parsing where contradictious information can be ignored and lead to false assumptions. The accepted answer of #Arjun is completely wrong.
By the way: Please use Locale.US or new Locale("en", "US") instead of new Locale("en-US") because the language "en-US" does not exist.

How to convert date strings from different TimeZones to Date object in one TimeZone

Im working on an RSS reader software. I get items with their pubDate (publish date) values as string, convert them to Date object, and put them to my DB. However, when I check my DB, I saw some interesting values such as the date of tomorrow.
I research this situation and found that it is about time zone value Z. For example when I get "Mon, 26 May 2014 21:24:29 -0500", it becomes "2014-05-27 05:24:29", the next day !
All I want is to get dates in any timezone and convert them to date in common timezone, such as my country's.
Here is my code :
public static String convert(String datestr) throws ParseException {
DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
Date date = formatter.parse(datestr);
SimpleDateFormat resultFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return resultFormatter.format(date);
}
And I use the method like that :
System.out.println(convert("Mon, 26 May 2014 21:24:29 -0500"));
The output is : 2014-05-27 05:24:29
Any idea ?
Since you haven't set a time zone, it's using your system's default.
Set a specific IANA time zone.
SimpleDateFormat resultFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
resultFormatter.setTimeZone(TimeZone.getTimeZone("America/New_York"));
return resultFormatter.format(date);
Looks like you passed a Date with timezone, but given a wrong format. If you are passing timezone like "-0500" you should rather use:
DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");
Remember that the system will always display the date using the current, default timezone (TimeZone.getDefault()) unless you override it by:
resultFormatter.setTimeZone(...)
This is working as expected. The date is converted as per your system's timezone.
Check the UTC offset of your system and replace it in the sample date string and look at the output.
For e.g: India is UTC+5:30
String datestr="Mon, 26 May 2014 21:24:29 +0530";
output:
2014-05-26 21:24:29
Alternate solution
If you don't want to consider the timezone of the input date string then simply truncate this information and remove zzz from pattern as well as shown in below code:
String datestr = "Mon, 26 May 2014 21:24:29 -0530";
datestr = datestr.replaceAll("\\s[-+](\\d+)$", ""); // truncate the timezone info if not needed
DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss"); // remove zzz from the pattern
Date date = formatter.parse(datestr);
SimpleDateFormat resultFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(resultFormatter.format(date));

Categories

Resources