Reputation: 571
I've got a silly problem, here's my code:
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss zZ",Locale.US);
System.out.println(dateFormat.format(new Date()));
try {
wou.setDateStart(dateFormat.parse(date));
wou.setDateEnd(dateFormat.parse(date));
} catch (ParseException e) {
System.out.println(e.getCause() + " " + e.getMessage());
e.printStackTrace();
}
the result is following:
Fri Jun 05 2015 15:34:29 GMT+0000
null Unparseable date: "Fri Jun 05 2015 17:30:00 GMT+0000"
What's wrong with my format? It outputs the current date in the same format as the date I want to parse, but keeps telling me that the date is unparseable...
I'm struggling that for over an hour and I'm completely lost...
EDIT:
I have no control over the date I need to parse (if I did, I would change it in a source to a format that I could consume)
Following code:
String date = request.getParameter("absencyDate");
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss z",Locale.US);
try {
System.out.println(dateFormat.format(new Date()));
System.out.println(date);
System.out.println(dateFormat.parse(date));
} catch (ParseException e1) {
Produces same error:
Fri Jun 05 2015 16:09:15 GMT
Fri Jun 05 2015 12:30:00 GMT+0000
java.text.ParseException: Unparseable date: "Fri Jun 05 2015 12:30:00 GMT+0000"
Upvotes: 2
Views: 2448
Reputation: 79085
The legacy date-time API (java.util
date-time types and their formatting API, SimpleDateFormat
) are outdated and error-prone. It is recommended to stop using them completely and switch to java.time
, the modern date-time API*.
Demo using modern date-time API:
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
public class Main {
public static void main(String args[]) {
String dateStr = "Fri Jun 05 2015 17:30:00 GMT+0000";
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("EEE MMM d u H:m:s")
.appendLiteral(' ')
.appendZoneId()
.appendPattern("X")
.toFormatter(Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(dateStr, dtf);
System.out.println(zdt);
}
}
Output:
2015-06-05T17:30Z[GMT]
For any reason, if you need an object of java.util.Date
from this object of ZonedDateTime
, you can so as follows:
Date date = Date.from(zdt.toInstant());
Learn more about the the modern date-time API* from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an 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.
Upvotes: 0
Reputation: 34628
The problem is your use of zZ
in the date format. It expects a simple name-based zone (z
), followed by an RFC-822 zone (Z
).
It works well if the default zone (or the zone set in the format) is not GMT, because then it just parses up to that point (matches the z
), and then it parses the +0000
as the Z
.
But when the zone is GMT, it actually tries to parse the part that follows it (+0000
) as part of the z
, because "GMT+hh:mm" is a valid zone for z
, and that fails.
The date format appears deceivingly correct. But combining two timezone formats is not. It should either be a named time zone (which includes "GMT+00:00"), or an RFC 822 offset (which doesn't include the "GMT" designation).
Edit following OP edit
So you get your date
parameter from somewhere, and they are sending it to you with a non-standard zone designation. GMT+0000
matches neither general time zone (should be GMT
or GMT+00:00
), RFC 822 time zone (should be +0000
without GMT
), nor ISO 8601 time zone (should be +00
or +0000
or +00:00
).
If you know that they will always be using GMT
in their dates, I think the best you can do is:
"EEE MMM dd yyyy HH:mm:ss 'GMT'Z"
Which will take the GMT
part as a literal string rather than a time zone designator, then interpret the time zone from whatever follows it.
Or if the source that generates that parameter is under your control, fix its format to use a proper time zone matching one of the standards.
Upvotes: 4