更改Java时间戳格式会导致更改时间戳 [英] Changing Java Timestamp format causes a change of the timestamp

查看:200
本文介绍了更改Java时间戳格式会导致更改时间戳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Java时间戳格式化函数感到有些困惑,因为它们似乎将时间戳更改了几分钟。

I'm a bit puzzled regarding the Java timestamp formatting functions as they seem to change the timestamp by a few minutes.

我的Pivotal CloudFoundry应用程序写了一个新条目进入PostgreSQL 9.4.5数据库。这样做,我让PostgreSQL生成并存储该条目的时间戳(在SQL语句中,我对该特定列使用'now()')。
到目前为止一切正常。当我用我的应用程序读取条目时出现问题,因为我必须将时间戳格式化为ISO 8601(公司策略),这似乎改变了时间戳。我已经使用了这段代码:

My Pivotal CloudFoundry app writes a new entry into a PostgreSQL 9.4.5 database. Doing so, I let PostgreSQL generate and store a timestamp for that entry (within the SQL statement I use 'now()' for that particular column). All that works fine so far. Problems arise when I read the entry with my app because I have to format the timestamp to ISO 8601 (company policy) and this seems to change the timestamp. I've used this code:

public String parseTimestamp(String oldDate) {
    System.out.println("String oldDate: " + oldDate);

    TimeZone timeZone = TimeZone.getTimeZone("Europe/Berlin");
    SimpleDateFormat oldDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSS");
    SimpleDateFormat newDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
    newDateFormat.setTimeZone(timeZone);

    Date tempDate = null;
    try {
        tempDate = oldDateFormat.parse(oldDate);
    } catch (ParseException e) {
        //TODO
    }

    System.out.println("tempDate before format(): " + tempDate);
    String newDate = newDateFormat.format(tempDate);
    System.out.println("tempDate after format(): " + tempDate);
    System.out.println("String newDate: " + newDate);
    return newDate;
}

输出:

String oldDate: 2018-06-18 13:07:27.624828+02
tempDate before format(): Mon Jun 18 13:17:51 CEST 2018
tempDate after format(): Mon Jun 18 13:17:51 CEST 2018
String newDate: 2018-06-18T13:17:51Z

如您所见,时间戳从13:07变为13:17。所有其他查询条目也显示出差异,在~2到10分钟之间变化。但是,当我重新运行查询时,每个差异都保持不变。 OP告诉我,所有涉及的系统都有同步时间,我不确定系统时间是否应该在这里发挥作用。

As you can see, the timestamp changed from 13:07 to 13:17. All the other queried entries also show a difference, varying between ~2 to 10 minutes. However, when I re-run the query, each difference stays the same. OPs told me that all involved systems have synchronised time and I'm not sure if system time should play a role here at all.

有人知道发生了什么吗?

Does someone know what is going on?

推荐答案

首先,我真的很困惑并且想到,你可能在 SimpleDateFormat 中发现了某种错误。您的代码可以缩减为以下行以显示相同的行为:

First, I was really puzzled and thought, you might have found some kind of bug in SimpleDateFormat. Your code can be reduced to the following lines to show the same behaviour:

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSS");
String str = "2018-06-18 13:07:27.624828+02";
System.out.println(str);
System.out.println(format.parse(str));

结果:

2018-06-18 13:07:27.624828+02
Mon Jun 18 13:17:51 CEST 2018

解析后的日期对象又增加了10分钟(以及几秒钟)。

The parsed Date object got ten additional minutes (and some seconds).

仔细看看会发现问题 - 它不是JDK中的错误:

Taking a closer look reveals the problem - it is NOT a bug in JDK:

你的毫秒部分 624828 - 这些是六(!)位(不是三位)。 624828毫秒约为624秒,即10分24秒。
SimpleDateFormat 正确地总结了这个额外的秒和分钟。

Your millisecond-part is 624828 - these are six(!) digits (not three). 624828 milliseconds are about 624 seconds, which are 10 minutes and 24 seconds. The SimpleDateFormat correctly summed up this additional seconds and minutes.

还有什么不对:你的日期格式包含五位数的毫秒部分。

What's wrong too: Your date format contains five digits for the milliseconds part.

解决方案:

(新的) Java Time API 可以处理更大的一秒 - 并且还可以在不同的时区之间轻松转换:

The (new) Java Time API can handle larger fractions of a second - and also convert easily between different time zones:

String str = "2018-06-18 13:07:27.624828+02";
DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSx");
OffsetDateTime date = OffsetDateTime.parse(str, pattern);
System.out.println(date);
System.out.println(date.withOffsetSameInstant(ZoneOffset.UTC));

结果:

2018-06-18T13:07:27.624828+02:00
2018-06-18T11:07:27.624828Z

这篇关于更改Java时间戳格式会导致更改时间戳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆