2

我们目前正在替换SimpleDateFormatDateTimeFormatter. 在此期间,我遇到了一个奇怪的行为。以毫秒为单位的差异我无法向自己解释。这是代码:

val timeString = "2021-09-17T13:37:00.09Z"
val newFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX").withZone(ZoneId.of("UTC"))
val oldFormatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.US)

val zonedDateTime = newFormatter.parse(timeString)
val newFormatterDate = Date.from(zonedDateTime.toInstant())
val oldFormatterDate = oldFormatter.parse(timeString)

Assert.assertEquals(newFormatterDate, oldFormatterDate) // false
// newFormatterDate.time is 1631885820090 and 
// oldFormatterDate.time is 1631885820009

我在这里发现很多帖子说我们不应该再使用SimpleDateFormat了。

但是有人可以向我解释这是怎么发生的吗?我们的代码中是否有错误或误解了什么?

编辑:@Ole VV 的链接提供的解决方案(如何在 java 中用两个或三个毫秒数字解析日期时间?)可能会解决我遇到的错误,但它不能回答问题/解释为什么这两个格式化程序会产生不同的结果。

4

2 回答 2

3

现代,DateTimeFormatter将秒后的数字视为秒的分数,而传统,SimpleDateFormat将秒后的数字视为毫秒数。

让我们看看如何DateTimeFormatter处理它:

0.09 seconds = 0.09 * 1000 ms = 90 ms

另一方面,SimpleDateFormat将其处理为09毫秒 =9毫秒。

顺便说一句,在使用现代日期时间 API 时,您不需要DateTimeFormatter显式使用 a 来解析您的日期时间字符串,因为它已经是 ISO 8601 格式。现代日期时间 API 基于ISO 8601DateTimeFormatter ,只要日期时间字符串符合 ISO 8601 标准,就不需要明确使用对象。

演示:

import java.time.Instant;

public class Main {
    public static void main(String[] args) {
        System.out.println(Instant.parse("2021-09-17T13:37:00.09Z").toEpochMilli());
    }
}

输出:

1631885820090

Trail: Date Time了解有关现代日期时间 API *的更多信息。


* 如果您正在为一个 Android 项目工作,并且您的 Android API 级别仍然不符合 Java-8,请通过 desugaring 检查可用的 Java 8+ API。请注意,Android 8.0 Oreo 已经提供java.time.

于 2021-10-05T11:21:02.957 回答
1

Your input data has two digits for fractional seconds. Your input patterns have three. The implementations interpret differently what 09 fractional seconds mean when three digits are expected.

If possible, fix either your input data or your input pattern to agree on the number of fractional digits. If you need to accept both two or three digits of fractional seconds, have a look at How to parse date-time with two or three milliseconds digits in java?

于 2021-10-05T08:14:18.993 回答