I am struggling with this .. I have an input string - like this: 2021-10-13 11:33:16.000-04
Using Java.
I need to get a Date object from it. which formatting pattern can I use ?
I try with these
SimpleDateFormat inFormatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss.SSS'-'ZZ");
and
SimpleDateFormat inFormatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss.SSSZZ");
and I keep getting
java.text.ParseException: Unparseable date: "2021-10-13 11:33:16.000-04"
at java.base/java.text.DateFormat.parse(DateFormat.java:396)
at com.dima.tests.DatesConversions.main(DatesConversions.java:24)
Please, help !!
CodePudding user response:
Don't use Date as it is outdated. Use the classes in the java.time
OffsetDateTime odt = OffsetDateTime.parse(str,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSX"));
System.out.println(odt);
Prints
2021-10-13T11:33:16-04:00
CodePudding user response:
java.time
Even though you need to give an old-fashionede Date
object to a legacy API beyond your control, I still recommend that you use java.time, the modern Java date and time API, in your own code. The final conversion to Date
is pretty straight-forward.
I’d use this formatter for maximum reuse of existing formatters:
private static final DateTimeFormatter PARSER = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral(' ')
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.appendOffset(" HHmm", " 00")
.toFormatter(Locale.ROOT);
Then we parse and convert like this:
String input = "2021-10-13 11:33:16.000-04";
OffsetDateTime dateTime = OffsetDateTime.parse(input, PARSER);
System.out.println(dateTime);
Instant i = dateTime.toInstant();
Date oldfashionedDate = Date.from(i);
System.out.println(oldfashionedDate);
Output in my time zone, Europe/Copenhagen:
2021-10-13T11:33:16-04:00 Wed Oct 13 17:33:16 CEST 2021
Denmark is at offset 02:00 at this time of year, so 6 hours ahead of the UTC offset -04 from your string. Therefore Date.toString()
confusingly prints a clock hour that is 6 hours ahead of the original time of day.
Note: if your forward service accepts anything else than an old-fashioned Date
, you should not be using that class. For example, if a String
is required, the OffsetDateTime
that we got can be formatted into a new string using a second DateTimeFormatter
(or in lucky cases, its toString
method).
What went wrong in your code?
First, a UTC offset can have positive or negative sign. Instead of -04
you could have had for example 09
. Formatters are designed for to take the sign,
or -
, as part of the offset. Therefore hardcoding the minus sign as a literal, as in your first attempt, is bound to fail. In your second attempt, yyyy-MM-dd HH:mm:ss.SSSZZ
, you are already closer. However, ZZ
is for an offset with sign and four digits (like 0530
or -0400
; hour and minute), so does not work for a two-digit offset like -04
. Your SimpleDateFormat
expected more digits where your string ended and therefore threw the exception that you saw.
Link
Oracle tutorial: Date Time explaining how to use java.time.
CodePudding user response:
Since you are using ISO 8601 time zone
timezone, you have the use the below pattern.
SimpleDateFormat inFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSX");
And then, to get the date:
Date date = inFormatter.parse("2021-10-13 11:33:16.000-04");
Always check the documentation.