Jon Skeet的答案是正确且聪明的。您似乎只是看到了时区调整。你的两个字符串2021-03-12T10:42:01.000Z
&2021-03-12T12:42:01+0200
代表同一个时刻。中午 12 点(如果比 UTC 早两个小时)与上午 10 点相同,与 UTC 的偏移量为零时分秒。
而且,正如另一个答案中提到的那样,您确实应该避免使用与 Java 的最早版本捆绑在一起的糟糕的日期时间类。
tl;博士
myXMLGregorianCalendar // Legacy class, representing a moment as seen in some time zone.
.toGregorianCalendar() // Another legacy class, also representing a moment as seen in some time zone.
.toZonedDateTime() // A modern *java.time* class, representing a moment as seen in some time zone.
.toInstant() // Another *java.time* class, for representing a moment as seen in UTC.
.truncatedTo( // Lopping off some smaller part of the date-time value.
ChronoUnit.SECONDS // Specifying whole seconds as our granularity of truncation, so lopping off any fractional second.
) // Returns another `Instant` object, rather than altering (mutating) the original, per immutable objects pattern.
.toString() // Generating text representing the content of our `Instant` object, using standard ISO 8601 format.
java.time
现代方法使用java.time多年前取代SimpleDateFormat
, XMLGregorianCalendar
,GregorianCalendar
等的类。
转换遗留<——> 现代的
您可以轻松地将遗留类型转换为java.time。在旧类上寻找新to
/方法。from
ZonedDateTime zdt = myXMLGregorianCalendar.toGregorianCalendar().toZonedDateTime() ;
调整到零偏移
通过提取Instant
. 此类表示以 UTC 格式显示的时刻,始终以 UTC 格式表示。
Instant instant = zdt.toInstant() ;
理解这一点zdt
,instant
两者都代表同一时刻,时间轴上的同一点,但它们的挂钟时间不同。
截断
鉴于您的问题中看到的格式模式,您似乎希望使用整秒的粒度。要截断任何小数秒,请截断为秒。
Instant truncated = instant.truncatedTo( ChronoUnit.SECONDS ) ;
ISO 8601
您所需的文本格式在ISO 8601标准中定义。该标准在java.time中默认用于解析/生成字符串。因此无需指定任何格式模式。
String output = truncated.toString() ;