【问题标题】:DateTimeFormatter and SimpleDateFormat produce different results using same input stringDateTimeFormatter 和 SimpleDateFormat 使用相同的输入字符串产生不同的结果
【发布时间】:2021-11-24 23:34:47
【问题描述】:

我们目前正在将SimpleDateFormat 替换为DateTimeFormatter。 在此期间,我遇到了一个奇怪的行为。 毫秒之间存在差异,我无法向自己解释。 代码如下:

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 的链接 (How to parse date-time with two or three milliseconds digits in java?) 提供的解决方案可能会解决我遇到的错误,但它不能回答问题/解释为什么这两个格式化程序会产生不同的结果。

【问题讨论】:

标签: android simpledateformat datetimeformatter


【解决方案1】:

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

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

0.09 seconds = 0.09 * 1000 ms = 90 ms

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

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

演示:

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 了解有关 modern Date-Time API* 的更多信息。


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

【讨论】:

    【解决方案2】:

    您的输入数据有两位小数秒。您的输入模式有三个。当需要三位数时,实现对09 小数秒的含义有不同的解释。

    如果可能,请修正您的输入数据或输入模式以就小数位数达成一致。如果您需要同时接受两位或三位小数秒,请查看How to parse date-time with two or three milliseconds digits in java?

    【讨论】:

      猜你喜欢
      • 2019-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-29
      • 1970-01-01
      • 2016-08-17
      • 1970-01-01
      • 2020-07-09
      相关资源
      最近更新 更多