我尝试使用
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基于ISO8601,只要日期时间字符串符合ISO8601标准,就不需要显式使用DateTimeFormatter
对象。日期时间字符串中的Z
是零时区偏移量的时区指示符。它代表祖鲁,指定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
随着Java SE 8于2014年3月发布,过时且错误的传统日期时间API(java.util
日期时间类型及其格式类型、SimpleDateFormat
等)被java.time
(现代日期时间API*)所取代。强烈建议停止使用传统的API并切换到此新的API。如果您需要java.util.Date
,请使用java.util.Date#from(Instant)
获取。
java.util.Date date = Date.from(instant);
注意,java.util.Date
对象不是像现代日期时间类型那样的真实日期时间对象;而是表示自称为"0"的标准基准时间以来的毫秒数;"纪元";,即CCD_ 20(或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
从跟踪:日期时间了解有关java.time
的更多信息,即现代API日期时间*。
*出于任何原因,如果您必须坚持使用Java 6或Java 7,您可以使用ThreeTen Backport将Java.time的大部分功能向后移植到Java 6&7.如果您正在为Android项目工作,并且您的Android API级别仍然不符合Java-8,请检查通过desugaring和如何在Android项目中使用ThreeTenABP提供的Java 8+API
对于如何将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);
Z
是祖鲁时区(即UTC时区),而不是文字Z。
整个格式是ISO-8601即时格式。
有一个预先存在的格式化程序:DateTimeFormatter#ISO_INSTANT
摘录自javadoc:
公共静态最终DateTimeFormatter ISO_INSTANT
ISO即时格式化程序,以UTC格式格式化或解析即时信息,如"2011-12-03T10:15:30Z"。
这返回一个不可变的格式化程序,能够格式化和解析ISO-8601即时格式。格式化时,总是输出分钟的秒。秒的nano根据需要输出零、三、六或九位数字。解析时,至少需要到秒字段的时间。解析从0到9的小数秒。未使用本地化的十进制样式。
这是一个特殊的格式化程序,旨在允许即时消息的可读形式。Instant类被设计为只表示一个时间点,并在内部存储从1970-01-01Z的固定历元开始的以纳秒为单位的值。因此,如果不提供某种形式的时区,即时消息就不能格式化为日期或时间。通过使用ZoneOffset.UTC.提供适当的转换,该格式化程序可以对Instant进行格式化
格式包括:
ISO_OFFSET_DATE_TIME,其中使用UTC偏移量从ChronoField.instant_SECONDS和ChronoField.NANO_OF_SOND转换瞬间。分析不区分大小写。
返回的格式化程序没有覆盖年表或区域。它使用STRICT解析器样式。
这似乎是默认格式,请尝试此格式。
ZonedDateTime dateTime = ZonedDateTime.parse("2020-07-28T14:28:52.877Z");
// In case you still need LocalDateTime
LocalDateTime localDateTime = dateTime.toLocalDateTime();