You do not need DateTimeFormatter
to parse your date-time string
Parse the given date string directly to OffsetDateTime
. The modern date-time API is based on ISO 8601 and does not require using a DateTimeFormatter
object explicitly as long as the date-time string conforms to the ISO 8601 standards. The Z
in your date-time string is the timezone designator for zero-timezone offset. It stands for Zulu and specifies the Etc/UTC
timezone (which has the timezone offset of +00:00
hours).
OffsetDateTime odt = OffsetDateTime.parse("2020-12-20T00:00:00.000Z");
Convert the OffsetDateTime
into Instant
Convert the OffsetDateTime
into Instant
using OffsetDateTime#toInstant
. An Instant
represents an instantaneous point on the timeline. It is independent of a timezone and thus, it is always in UTC.
Instant instant = odt.toInstant();
Stop using the legacy date-time API
With the release of Java SE 8 in March 2014, the outdated and error-prone legacy date-time API (java.util
date-time types and their formatting type, SimpleDateFormat
etc.) was supplanted by java.time
, the modern date-time API*. It is strongly recommended to stop using the legacy API and switch to this new API. If at all, you need java.util.Date
, get it using java.util.Date#from(Instant)
.
java.util.Date date = Date.from(instant);
Note that the java.util.Date
object is not a real date-time object like the modern date-time types; rather, it represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT
(or UTC). When you print an object of java.util.Date
, its toString
method returns the date-time in the JVM's timezone, calculated from this milliseconds value. If you need to print the date-time in a different timezone, you will need to set the timezone to SimpleDateFormat
and obtain the formatted string from it e.g.
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
System.out.println(sdf.format(date));
You can convert an Instant
to other date-time types
You can convert an Instant
to other date-time types easily e.g. if you want to convert it into a ZonedDateTime
instance representing the date-time in London, you can do so as
ZonedDateTime zdt = instant.atZone(ZoneId.of("Europe/London"));
LocalDateTime
is useless in your case
Quoted below is a very good description of the uses of LocalDateTime
:
This class can be used to represent a specific event, such as the
first race for the Louis Vuitton Cup Finals in the America's Cup
Challenger Series, which began at 1:10 p.m. on August 17, 2013. Note
that this means 1:10 p.m. in local time.
The best use of your date-time string is as an OffsetDateTime
which you have obtained in the first step itself.
Demo:
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Date;
public class Main {
public static void main(String[] args) {
// Parse the date-time string into OffsetDateTime
OffsetDateTime odt = OffsetDateTime.parse("2020-12-20T00:00:00.000Z");
System.out.println(odt);
// Convert OffsetDateTime into Instant
Instant instant = odt.toInstant();
// If at all, you need java.util.Date
Date date = Date.from(instant);
System.out.println(date);
// You can convert an `Instant` to other date-time types easily
// e.g. to ZoneDateTime in a specific timezone
ZonedDateTime zdt = instant.atZone(ZoneId.of("Europe/London"));
System.out.println(zdt);
// e.g. to OffsetDateTime with a specific timezone offset
OffsetDateTime odt0530 = instant.atOffset(ZoneOffset.of("-05:30"));
System.out.println(odt0530);
// e.g. to LocalDateTime via an OffsetDateTime or a ZonedDateTime
LocalDateTime ldt = odt.toLocalDateTime();
System.out.println(ldt);
}
}
Output:
2020-12-20T00:00Z
Sun Dec 20 00:00:00 GMT 2020
2020-12-20T00:00Z[Europe/London]
2020-12-19T18:30-05:30
2020-12-20T00:00
Learn more about java.time
, 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.
java.util.Date
if you can avoid it. UseInstant
instead. – Lungwort