java - FastDateFormat 解析器输出不正确的时间

标签 java timestamp apache-commons

我一直在绞尽脑汁试图理解为什么 FastDateFormat 解析器返回的时间非常不正确。我尝试转换的字符串时间戳采用 GMT/UTC 格式,我正尝试将其插入 DB2 中的时间戳列。

代码如下:

String gmtTimestamp = "2017-03-12 02:38:30.417000000";
FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss.SSSSSSSSS", TimeZone.getTimeZone("GMT"));
java.util.Date d = fdf.parse(gmtTimestamp);
Timestamp ts1 = new Timestamp(d.getTime());
System.out.println(ts1);

打印出来的时间是:“2017-03-16 17:28:30.0”,倒计时4天近15个小时。这里发生了什么?

最佳答案

长话短说

    String gmtTimestamp = "2017-03-12 02:38:30.417000000";
    DateTimeFormatter dtf 
            = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSSSSSSS");
    Instant i1 = LocalDateTime.parse(gmtTimestamp, dtf)
            .atOffset(ZoneOffset.UTC)
            .toInstant();
    System.out.println(i1);

这打印

2017-03-12T02:38:30.417Z

Instant.toString() 的隐式调用会生成 UTC 日期和时间(我们的目的与 GMT 相同),因此您可以从 GMT 字符串中识别日期和时间。

java.time

我建议您删除 java.sql.Timestamp 类。它早就过时了,今天我们在 java.time 中有了更好的东西,现代 Java 日期和时间 API。 Timestamp 的最初目的是在 SQL 数据库中存储和检索日期时间值。使用足够新的 JDBC 驱动程序 (JDBC 4.2),您可以并且将希望利用 java.time 中的两个类来实现该目的:Instant timeline 和 LocalDateTime 表示没有时区的日期和时间。

如果您确实需要Timestamp(例如您不想立即升级的遗留 API 或较旧的 JDBC 驱动程序),请转换 Instant从上面到 Timestamp 就在将它交给遗留 API 或数据库之前:

    Timestamp ts1 = Timestamp.from(i1);
    System.out.println(ts1);

在美国/芝加哥时区运行,打印:

2017-03-11 20:38:30.417

Timestamp.toString() 获取 JVM 的时区设置并输出该时区的日期和时间(这可能会造成混淆)。

您的代码片段中发生了什么?

FastDateFormat 使用 SimpleDateFormat 格式模式。在 SimpleDateFormatFastDateFormat 中,大写 S 表示毫秒。所以 417000000 被视为毫秒(你想要的是 417 毫秒),它与 4 天 20 小时完全相同,它被添加到日期时间值直到秒。我使用 SimpleDateFormat 重现了您的结果,并将我的 JVM 设置为美国/芝加哥时区。 3 月份距 UTC -5 小时的其他时区将产生相同的结果。由于 Timestamp 是在偏移量 -5:00 处打印的,因此输出中的明显差异略小于 4 天 20 小时的实际差异,“仅”4 天 15 小时。

相比之下,尽管现代 DateTimeFormatter 大多使用相同的格式模式字母,但大写 S 表示秒的小数部分,这就是我们得到预期的 30.417 秒的原因和期望。

行情

All patterns are compatible with SimpleDateFormat (except time zones and some year patterns - see below).

( FastDateFormat documentation )

S Millisecond Number 978

( SimpleDateFormat documentation )

关于java - FastDateFormat 解析器输出不正确的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47835723/

相关文章:

java - 生成一个新字符串

java - 梅文。快照更新(首次下载)不起作用

python - 比较 Pandas 中两个数据框的索引中的值

python matplotlib 以小时格式设置 xticks

java - 为什么 Java 找不到 CLASSPATH 中的类?

java - 使用 apache commons 的 RandomStringUtils 生成唯一键

java - Eclipse subversion svn不上传目录

php - 从 MySQL 表中列出每小时的点击次数

java - Apache Commons Configuration2 如何从 InputStream 读取数据

java - 将带有 html/Javascript 的字符串放入 selenium webdriver