java.time and ThreeTenABP
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");
String instantString = "2020-02-05T03:17:04.000Z";
Instant i = Instant.parse(instantString);
ZonedDateTime dateTime = i.atZone(ZoneId.systemDefault());
String fechaConvert = dateTime.format(timeFormatter);
System.out.println("Converted time: " + fechaConvert);
I ran this snippet with my JVM time zone set to America/Guayaquil (Ecuador time) and got:
Converted time: 22:17
(Many other time zones are used in different parts of South America.)
Your string is in the ISO 8601 format for an instant (a point in time). Instant.parse()
expects this format, so we need no explicit formatter for parsing.
The date and time classes that you were trying to use, SimpleDateFormat
and Date
, are poorly designed and long outdated, the former in particular notoriously troublesome. Instead I am using java.time, the modern Java date and time API. I frankly find it a lot nicer to work with.
What went wrong in your code?
One of the many confusing traits of SimpleDatFormat
is that it is happy only to parse as much of the given string as it can and tacitly ignore the rest. The Z
in your string tells us that the date and time is in UTC, but your SimpleDateFormat
ignores this crucial fact. It therefore parses the date and time as though they were in your own time zone. The second SimpleDateFormat
instance then formats the wrong time back and gives you the time that was in the string, 03:17
(in this example).
As Andreas said, from API level 24 SimpleDateFormat
can correctly parse the Z
. On lower API levels it cannot. In contrast java.time has been backported and works on lower API levels too.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
- In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
- In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
- On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from
org.threeten.bp
with subpackages.
Links