Reputation: 122
I used the follow code to parse datetime
:
String parseDate(String tranDateTime, String originalDateFormat, String toDateFormat) throws ParseException {
SimpleDateFormat originalMonthYear = new SimpleDateFormat(originalDateFormat);
Date date = originalMonthYear.parse(tranDateTime);
SimpleDateFormat formatter = new SimpleDateFormat(toDateFormat);
return formatter.format(date);
}
And tried to parse a datetime value as below :
parseDate("2017-08-16T00:00:00Z",
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX", "yyyy-MM-dd HH:mm:ss");
An exception is thrown :
java.text.ParseException: Unparseable date: "2017-08-16T00:00:00Z"
However, when I change date value to "2017-08-16T02:54:15.537Z"
, the function worked fine. I don't know why.
Upvotes: 1
Views: 6645
Reputation: 86399
You asked in a comment:
Moreover, the datetime value could be "2017-08-16T00:00:00Z" or "2017-08-16T00:00:15.537Z" retrieved from database. Do we have a general pattern to parse both formats?
Even better, they can both be parsed without an explicit pattern:
System.out.println(OffsetDateTime.parse("2017-08-16T00:00:00Z"));
System.out.println(OffsetDateTime.parse("2017-08-16T00:00:15.537Z"));
This prints:
2017-08-16T00:00Z
2017-08-16T00:00:15.537Z
To format, for example:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(OffsetDateTime.parse("2017-08-16T00:00:00Z").format(formatter));
This prints
2017-08-16 00:00:00
I am using and warmly recommending java.time
, the modern Java date and time API. SimpleDateFormat
and Date
are long outmoded and the former in particular notoriously troublesome. The modern API is so much nicer to work with.
Your strings (in spite of differences) both conform to ISO 8601, the standard for date and time formats. The java.time
classes parse these formats without any explicit formatter.
Link: Oracle tutorial: Date Time explaining how to use java.time
Upvotes: 3
Reputation: 1748
Problem source :
The problem come from trying to pars date value 2017-08-16T00:00:00Z
with a date format yyyy-MM-dd'T'HH:mm:ss.SSSXXX
, in the line :
Date date = originalMonthYear.parse(tranDateTime);
See the difference between the value and format:
______________________________
|2017|08|16| T |00|00|00Z |
|yyyy|MM|dd|'T'|HH|mm|ss.SSSXXX|
|____|__|__|___|__|__|_________|
Solution :
Simple one is :
Date date = originalMonthYear.parse("2017-08-16T00:00:00.000Z")
But, if you will get many differents formats, you can use something like (never tested):
List<SimpleDateFormat> myUsedPatterns = new ArrayList<>();
myUsedPatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"));
myUsedPatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"));
for (SimpleDateFormat myPattern : myUsedPatterns) {
try {
SimpleDateFormat originalMonthYear = new SimpleDateFormat(myPattern );
Date date = originalMonthYear.parse(tranDateTime);
SimpleDateFormat formatter = new SimpleDateFormat(toDateFormat);
return formatter.format(date);
} catch (ParseException e) {
// Loop
}
}
Upvotes: 1
Reputation: 4558
The problem is coming from :
Date date = originalMonthYear.parse(tranDateTime);
This date
2017-08-16T00:00:00Z
Doesn't match the pattern
yyyy-MM-dd'T'HH:mm:ss.SSSXXX
Because milliseconds are missing (SSS
part)
So
Date date = originalMonthYear.parse(tranDateTime);
Throws the exception
java.text.ParseException: Unparseable date: "2017-08-16T00:00:00Z"
Solutions
2017-08-16T00:00:00Z
into 2017-08-16T00:00:00.000Z
(add milliseconds to your date)yyyy-MM-dd'T'HH:mm:ss.SSSXXX
into yyyy-MM-dd'T'HH:mm:ssXXX
(remove milliseconds from your pattern)Upvotes: 6
Reputation: 81
Change 2017-08-16T00:00:00Z
to 2017-08-16T00:00:00.000Z
, it works for me.
Upvotes: 1