android - DateTimeFormatter 和 SimpleDateFormat 使用相同的输入字符串产生不同的结果

标签 android simpledateformat datetimeformatter

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

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

最佳答案

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

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

0.09 seconds = 0.09 * 1000 ms = 90 ms

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

顺便说一句,在使用现代日期时间 API 时,您不需要显式使用 DateTimeFormatter 来解析日期时间字符串,因为它已经采用 ISO 8601 格式。现代日期时间 API 基于 ISO 8601并且不需要显式使用 DateTimeFormatter 对象,只要日期时间字符串符合 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

了解有关 modern Date-Time API 的更多信息* 来自 Trail: Date Time


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

关于android - DateTimeFormatter 和 SimpleDateFormat 使用相同的输入字符串产生不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69437741/

相关文章:

android - 如何显示和隐藏 popupWindow

java - 使用 Java 8 日期时间 API 时如何将 AM/PM 符号更改为我自己的字母表

java - SimpleDateFormat 返回带有无效日期字符串的奇怪日期

允许 -/或 .作为日期内的分隔符

Java:如何获得下一次匹配模式

java - 如何更改按钮单击 android 上的 Activity

javascript - 如何在 Android 中的 MHTML 文件上应用 javaScript 函数?

java - DateTimeFormatter 是否依赖于操作系统?

java - 获取运行时错误 "java.lang.IllegalStateException: Could not execute method for android:onClick"