将“2020-12-20T00:00:00.000Z”转换为java.util.Date?

huangapple go评论60阅读模式
英文:

How to convert "2020-12-20T00:00:00.000Z" to java.util.Date?

问题

我尝试使用

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH);
LocalDate date = LocalDate.parse(d.toString(), formatter);

但它抛出了一个错误。

有没有办法将JSON默认时间戳转换?

英文:

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?

答案1

得分: 8

你需要使用 LocalDateTime

DateTimeFormatter formatter = 
        DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH);
LocalDateTime date = LocalDateTime.parse(d.toString(), formatter);
英文:

You need to use LocalDateTime.

DateTimeFormatter formatter = 
        DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH);
LocalDateTime date = LocalDateTime.parse(d.toString(), formatter);

</details>



# 答案2
**得分**: 4

你不需要使用 `DateTimeFormatter` 来解析你的日期时间字符串。

将给定的日期字符串直接解析为 `OffsetDateTime`。现代日期时间API基于[ISO 8601](https://en.wikipedia.org/wiki/ISO_8601),只要日期时间字符串符合ISO 8601标准,就不需要显式使用`DateTimeFormatter`对象。你日期时间字符串中的`Z`是时区标识符,表示零时区偏移。它代表Zulu并指定`Etc/UTC`时区(时区偏移为`+00:00`小时)。
```java
OffsetDateTime odt = OffsetDateTime.parse("2020-12-20T00:00:00.000Z");

OffsetDateTime 转换为 Instant

使用 OffsetDateTime#toInstantOffsetDateTime 转换为 InstantInstant表示时间线上的瞬时点。它与时区无关,因此始终处于UTC。

Instant instant = odt.toInstant();

停止使用过时的日期时间API

自2014年3月发布Java SE 8以来,已经停用了过时且容易出错的旧日期时间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 对象不是像现代日期时间类型那样的真正日期时间对象;它代表的是自标准基准时间以来的毫秒数,即1970年1月1日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,你在第一步已经获得了它。

有关 java.time现代日期时间API的更多信息,请参阅 Trail: Date Time

<sup>* 如果出于任何原因,你必须坚持使用Java 6或Java 7,你可以使用ThreeTen-Backport,它将大多数java.time功能回退到Java 6和7。如果你正在进行Android项目,并且你的Android API级别仍不符合Java 8,请检查通过desugaring可用的Java 8+ API以及如何在Android项目中使用ThreeTenABP

英文:

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(&quot;2020-12-20T00:00:00.000Z&quot;);

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<sup>*</sup>. 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(&quot;yyyy-MM-dd&#39;T&#39;HH:mm:ss.SSSXXX&quot;, Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone(&quot;America/New_York&quot;));
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(&quot;Europe/London&quot;));

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(&quot;2020-12-20T00:00:00.000Z&quot;);
		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(&quot;Europe/London&quot;));
		System.out.println(zdt);

		// e.g. to OffsetDateTime with a specific timezone offset
		OffsetDateTime odt0530 = instant.atOffset(ZoneOffset.of(&quot;-05:30&quot;));
		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<sup>*</sup> from Trail: Date Time.


<sup>* 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.
</sup>

答案3

得分: 3

对于你关于如何将 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);
英文:

To your question on how to convert LocalDate to java.util.Date, you can use Date.from method as follows. Let me know if that is what you are expecting to achieve.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern(&quot;yyyy-MM-dd&#39;T&#39;HH:mm:ss.SSS&#39;Z&#39;&quot;, Locale.ENGLISH);
LocalDate localDate = LocalDate.parse(&quot;2020-12-20T00:00:00.000Z&quot;, formatter);
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
System.out.println(date);

答案4

得分: 2

Z代表Zulu时区(即UTC时区),而不是字面上的Z。

整个格式是ISO-8601的瞬时格式。

已经存在一个用于此目的的格式化程序:DateTimeFormatter#ISO_INSTANT

从Javadoc中提取的信息:

public static final DateTimeFormatter ISO_INSTANT

ISO瞬时格式化程序,用于格式化或解析UTC中的瞬时时间,例如'2011-12-03T10:15:30Z'。

返回一个不可变格式化程序,能够格式化和解析ISO-8601的瞬时格式。在格式化时,总是输出秒。纳秒输出零、三、六或九位数字,视情况而定。在解析时,至少需要秒字段。可以解析从零到九的小数秒。不使用本地化的小数样式。

这是一个特殊的格式化程序,旨在允许以人类可读的形式表示Instant。Instant类设计为仅表示时间点,并在内部以自1970-01-01Z的固定纪元的纳秒值存储值。因此,Instant不能在没有提供某种形式的时区的情况下格式化为日期或时间。此格式化程序允许通过使用ZoneOffset.UTC提供的适当转换来格式化Instant。

该格式包括:

ISO_OFFSET_DATE_TIME,其中瞬时时间从ChronoField.INSTANT_SECONDS和ChronoField.NANO_OF_SECOND使用UTC偏移进行转换。解析不区分大小写。

返回的格式化程序没有覆盖纪元或时区。它使用STRICT解析器样式。

英文:

The Z is the Zulu time-zone (i.e. the UTC time-zone), not a literal Z.

This whole format is the ISO-8601 instant format.

There is a pre-existing formatter for that: DateTimeFormatter#ISO_INSTANT

Extract from the javadoc:
> public static final DateTimeFormatter ISO_INSTANT
>
>The ISO instant formatter that formats or parses an instant in UTC, such as '2011-12-03T10:15:30Z'.
>
>This returns an immutable formatter capable of formatting and parsing the ISO-8601 instant format. When formatting, the second-of-minute is always 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. 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. As such, an Instant cannot be formatted as a date or time without providing some form of time-zone. This formatter allows the Instant to be formatted, by providing a suitable conversion using ZoneOffset.UTC.
>
>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. Parsing is case insensitive.
>
>The returned formatter has no override chronology or zone. It uses the STRICT resolver style.

答案5

得分: 1

这似乎是默认格式,请尝试这个。

ZonedDateTime dateTime  = ZonedDateTime.parse("2020-07-28T14:28:52.877Z");

// 如果您仍然需要LocalDateTime
LocalDateTime localDateTime  = dateTime.toLocalDateTime();

英文:

This seems to be default format, please try this one.

ZonedDateTime dateTime  = ZonedDateTime.parse(&quot;2020-07-28T14:28:52.877Z&quot;);

// In case you still need LocalDateTime
LocalDateTime localDateTime  = dateTime.toLocalDateTime();

huangapple
  • 本文由 发表于 2020年7月29日 23:21:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/63156952.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定