您不需要DateTimeFormatter 来解析您的日期时间字符串
将给定的日期字符串直接解析为OffsetDateTime。现代日期时间 API 基于 ISO 8601 并且不需要明确使用 DateTimeFormatter 对象,只要日期时间字符串符合 ISO 8601 标准。日期时间字符串中的 Z 是零时区偏移量的 timezone designator。它代表 Zulu 并指定 Etc/UTC 时区(其时区偏移量为 +00:00 小时)。
OffsetDateTime odt = OffsetDateTime.parse("2020-12-20T00:00:00.000Z");
将OffsetDateTime 转换为Instant
使用OffsetDateTime#toInstant 将OffsetDateTime 转换为Instant。 Instant 代表时间线上的一个瞬时点。它独立于时区,因此始终采用 UTC。
Instant instant = odt.toInstant();
停止使用旧的日期时间 API
随着 2014 年 3 月 Java SE 8 的发布,过时且容易出错的旧版日期时间 API(java.util 日期时间类型及其格式类型,SimpleDateFormat 等)被java.time 取代,modern date-time API*。强烈建议停止使用旧版 API 并切换到此新 API。如果需要 java.util.Date,请使用 java.util.Date#from(Instant) 获取。
java.util.Date date = Date.from(instant);
注意java.util.Date 对象不是像modern date-time types 那样的真实日期时间对象;相反,它表示自称为“纪元”的标准基准时间以来的毫秒数,即January 1, 1970, 00:00:00 GMT(或 UTC)。当你打印一个java.util.Date 的对象时,它的toString 方法会返回JVM 时区中的日期时间,根据这个毫秒值计算得出。如果您需要在不同的时区打印日期时间,则需要将时区设置为 SimpleDateFormat 并从中获取格式化字符串,例如
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));
您可以将Instant 转换为其他日期时间类型
您可以轻松地将Instant 转换为其他日期时间类型,例如如果您想将其转换为代表伦敦日期时间的ZonedDateTime 实例,您可以这样做
ZonedDateTime zdt = instant.atZone(ZoneId.of("Europe/London"));
LocalDateTime 在你的情况下没用
Quoted below很好的描述了LocalDateTime的用途:
此类可用于表示特定事件,例如
美洲杯路易威登杯总决赛的第一场比赛
挑战者系列赛于下午 1:10 开始。 2013 年 8 月 17 日。 注
这意味着下午 1:10在当地时间。
日期时间字符串的最佳用途是作为您在第一步中获得的OffsetDateTime。
演示:
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);
}
}
输出:
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
了解更多关于java.time,modern date-time API* 来自Trail: Date Time。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 Android 项目工作,并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。