我试着用
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH);
LocalDate date = LocalDate.parse(d.toString(), formatter);
但它会引发错误。
有什么方法可以转换 JSON 默认时间戳?
我试着用
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH);
LocalDate date = LocalDate.parse(d.toString(), formatter);
但它会引发错误。
有什么方法可以转换 JSON 默认时间戳?
你需要使用LocalDateTime
.
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH);
LocalDateTime date = LocalDateTime.parse(d.toString(), formatter);
DateTimeFormatter
解析日期时间字符串将给定的日期字符串直接解析为OffsetDateTime
. 现代日期时间 API 基于ISO 8601DateTimeFormatter
,只要日期时间字符串符合 ISO 8601 标准,就不需要显式使用对象。您的Z
日期时间字符串中的 是零时区偏移的时区指示符。它代表 Zulu 并指定Etc/UTC
时区(时区偏移量为+00:00
小时)。
OffsetDateTime odt = OffsetDateTime.parse("2020-12-20T00:00:00.000Z");
OffsetDateTime
成Instant
转换OffsetDateTime
成Instant
使用OffsetDateTime#toInstant
. AnInstant
代表时间线上的一个瞬时点。它独立于时区,因此始终采用 UTC。
Instant instant = odt.toInstant();
随着 2014 年 3 月 Java SE 8 的发布,过时且容易出错的遗留日期时间 API(java.util
日期时间类型及其格式化类型等)SimpleDateFormat
被现代日期时间 API *取代。强烈建议停止使用旧版 API 并切换到此新 API。如果有需要,请使用.java.time
java.util.Date
java.util.Date#from(Instant)
java.util.Date date = Date.from(instant);
请注意,该java.util.Date
对象不是像现代日期时间类型那样的真实日期时间对象;相反,它表示自称为“纪元” 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
在你的情况下没用下面引用的是对 用途的非常好的描述LocalDateTime
:
此类可用于表示特定事件,例如美洲杯挑战者系列赛路易威登杯总决赛的第一场比赛,比赛于 2013 年 8 月 17 日下午 1:10 开始。请注意,这意味着下午 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
从Trail: Date Time了解更多关于java.time
现代日期时间 API *的信息。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,则可以使用ThreeTen-Backport,它将大部分java.time功能向后移植到 Java 6 和 7。如果您正在为 Android 项目和 Android API 工作level 仍然不符合 Java-8,请检查Java 8+ APIs available through desugaring和How to use ThreeTenABP in Android Project。
这Z
是 Zulu 时区(即 UTC 时区),而不是文字 Z。
整个格式是 ISO-8601 即时格式。
有一个预先存在的格式化程序:DateTimeFormatter#ISO_INSTANT
从 javadoc 中提取:
公共静态最终日期时间格式化程序 ISO_INSTANT
以 UTC 格式格式化或解析瞬间的 ISO 瞬间格式化程序,例如“2011-12-03T10:15:30Z”。
这将返回一个能够格式化和解析 ISO-8601 即时格式的不可变格式化程序。格式化时,总是输出秒数。纳秒根据需要输出零、三、六或九位数字。解析时,至少需要秒字段的时间。解析从零到九的小数秒。不使用本地化的十进制样式。
这是一个特殊的格式化程序,旨在允许 Instant 的人类可读形式。Instant 类旨在仅表示一个时间点,并在内部存储从 1970-01-01Z 的固定时期开始的以纳秒为单位的值。因此,在不提供某种形式的时区的情况下,Instant 不能被格式化为日期或时间。此格式化程序允许通过使用 ZoneOffset.UTC 提供合适的转换来格式化 Instant。
格式包括:
使用 UTC 偏移量从 ChronoField.INSTANT_SECONDS 和 ChronoField.NANO_OF_SECOND 转换瞬间的 ISO_OFFSET_DATE_TIME。解析不区分大小写。
返回的格式化程序没有覆盖年表或区域。它使用 STRICT 解析器样式。
这似乎是默认格式,请试试这个。
ZonedDateTime dateTime = ZonedDateTime.parse("2020-07-28T14:28:52.877Z");
// In case you still need LocalDateTime
LocalDateTime localDateTime = dateTime.toLocalDateTime();
对于如何转换LocalDate
为的问题java.util.Date
,您可以使用Date.from
以下方法。让我知道这是否是您期望实现的目标。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH);
LocalDate localDate = LocalDate.parse("2020-12-20T00:00:00.000Z", formatter);
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
System.out.println(date);