更改Java时间戳格式会导致更改时间戳 [英] Changing Java Timestamp format causes a change of the timestamp
问题描述
我对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屋!