[英]How to convert “2020-12-20T00:00:00.000Z” to java.util.Date?
I tried to use我试着用
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH);
LocalDate date = LocalDate.parse(d.toString(), formatter);
but it throws an error.但它会引发错误。
Is there any way to convert the JSON default timestamp?有什么方法可以转换 JSON 默认时间戳?
You need to use LocalDateTime
.您需要使用LocalDateTime
。
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH);
LocalDateTime date = LocalDateTime.parse(d.toString(), formatter);
The Z
is the Zulu time-zone (ie the UTC time-zone), not a literal Z. Z
是祖鲁时区(即 UTC 时区),而不是文字 Z。
This whole format is the ISO-8601 instant format.整个格式是 ISO-8601 即时格式。
There is a pre-existing formatter for that: DateTimeFormatter#ISO_INSTANT有一个预先存在的格式化程序: DateTimeFormatter#ISO_INSTANT
Extract from the javadoc:从 javadoc 中提取:
public static final DateTimeFormatter ISO_INSTANT公共 static 最终 DateTimeFormatter ISO_INSTANT
The ISO instant formatter that formats or parses an instant in UTC, such as '2011-12-03T10:15:30Z'.以 UTC 格式格式化或解析瞬间的 ISO 瞬间格式化程序,例如“2011-12-03T10:15:30Z”。
This returns an immutable formatter capable of formatting and parsing the ISO-8601 instant format.这将返回一个能够格式化和解析 ISO-8601 即时格式的不可变格式化程序。 When formatting, the second-of-minute is always output.格式化时,秒总是 output。 The nano-of-second outputs zero, three, six or nine digits digits as necessary.纳秒根据需要输出零、三、六或九位数字。 When parsing, time to at least the seconds field is required.解析时,至少需要秒字段的时间。 Fractional seconds from zero to nine are parsed.解析从零到九的小数秒。 The localized decimal style is not used.不使用本地化的十进制样式。
This is a special case formatter intended to allow a human readable form of an Instant.这是一个特殊的格式化程序,旨在允许 Instant 的人类可读形式。 The Instant class is designed to only represent a point in time and internally stores a value in nanoseconds from a fixed epoch of 1970-01-01Z. Instant class 旨在仅表示一个时间点,并在内部存储从 1970-01-01Z 的固定时期开始的以纳秒为单位的值。 As such, an Instant cannot be formatted as a date or time without providing some form of time-zone.因此,在不提供某种形式的时区的情况下,Instant 不能被格式化为日期或时间。 This formatter allows the Instant to be formatted, by providing a suitable conversion using ZoneOffset.UTC.此格式化程序允许通过使用 ZoneOffset.UTC 提供合适的转换来格式化 Instant。
The format consists of:格式包括:
The ISO_OFFSET_DATE_TIME where the instant is converted from ChronoField.INSTANT_SECONDS and ChronoField.NANO_OF_SECOND using the UTC offset.使用 UTC 偏移量从 ChronoField.INSTANT_SECONDS 和 ChronoField.NANO_OF_SECOND 转换瞬间的 ISO_OFFSET_DATE_TIME。 Parsing is case insensitive.解析不区分大小写。
The returned formatter has no override chronology or zone.返回的格式化程序没有覆盖年表或区域。 It uses the STRICT resolver style.它使用 STRICT 解析器样式。
This seems to be default format, please try this one.这似乎是默认格式,请试试这个。
ZonedDateTime dateTime = ZonedDateTime.parse("2020-07-28T14:28:52.877Z");
// In case you still need LocalDateTime
LocalDateTime localDateTime = dateTime.toLocalDateTime();
DateTimeFormatter
to parse your date-time string您不需要DateTimeFormatter
来解析您的日期时间字符串Parse the given date string directly to OffsetDateTime
.将给定的日期字符串直接解析为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.现代日期时间 API 基于ISO 8601 ,只要日期时间字符串符合 ISO 8601 标准,就不需要明确使用DateTimeFormatter
object。 The Z
in your date-time string is the timezone designator for zero-timezone offset.日期时间字符串中的Z
是零时区偏移的时区指示符。 It stands for Zulu and specifies the Etc/UTC
timezone (which has the timezone offset of +00:00
hours).它代表 Zulu 并指定Etc/UTC
时区(其时区偏移量为+00:00
小时)。
OffsetDateTime odt = OffsetDateTime.parse("2020-12-20T00:00:00.000Z");
OffsetDateTime
into Instant
将OffsetDateTime
转换为Instant
Convert the OffsetDateTime
into Instant
using OffsetDateTime#toInstant
.使用OffsetDateTime#toInstant
将OffsetDateTime
转换为Instant
。 An Instant
represents an instantaneous point on the timeline. Instant
表示时间线上的一个瞬时点。 It is independent of a timezone and thus, it is always in UTC.它独立于时区,因此始终采用 UTC。
Instant instant = odt.toInstant();
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 * . 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- 时间 API * 。 It is strongly recommended to stop using the legacy API and switch to this new API.强烈建议停止使用旧版 API 并切换到新版 API。 If at all, you need java.util.Date
, get it using java.util.Date#from(Instant)
.如果有的话,您需要java.util.Date
,使用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 ;请注意, java.util.Date
object 不是真正的日期时间 object 像现代日期时间类型; 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).相反,它表示自称为“纪元”的标准基准时间(即January 1, 1970, 00:00:00 GMT
(或 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.当您打印 java.util.Date 的java.util.Date
时,它的toString
方法返回 JVM 时区中的日期时间,这是根据这个毫秒值计算的。 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 eg如果您需要在不同的时区打印日期时间,则需要将时区设置为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
to other date-time types您可以将Instant
转换为其他日期时间类型You can convert an Instant
to other date-time types easily eg if you want to convert it into a ZonedDateTime
instance representing the date-time in London, you can do so as您可以轻松地将Instant
转换为其他日期时间类型,例如,如果要将其转换为代表伦敦日期时间的ZonedDateTime
实例,您可以这样做
ZonedDateTime zdt = instant.atZone(ZoneId.of("Europe/London"));
LocalDateTime
is useless in your case LocalDateTime
在您的情况下没用Quoted below is a very good description of the uses of LocalDateTime
: 下面引用的是对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 pm on August 17, 2013. Note that this means 1:10 pm in local time.此 class 可用于表示特定事件,例如美洲杯挑战者系列赛路易威登杯总决赛的第一场比赛,该比赛于 2013 年 8 月 17 日下午 1:10 开始。请注意,这意味着下午 1:10在当地时间。
The best use of your date-time string is as an OffsetDateTime
which you have obtained in the first step itself.您的日期时间字符串的最佳用途是作为您在第一步中获得的OffsetDateTime
。
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: 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 .从Trail: Date Time了解有关java.time
的更多信息,即现代日期时间 API * 。
* 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 . * 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级别仍然不符合 Java-8,请检查Java 8+ API 可通过脱糖和如何在 Android 项目中使用 ThreeTenABP 。
To your question on how to convert LocalDate
to java.util.Date
, you can use Date.from
method as follows.关于如何将LocalDate
转换为java.util.Date
的问题,您可以使用Date.from
方法,如下所示。 Let me know if that is what you are expecting to achieve.让我知道这是否是您期望实现的目标。
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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.