Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
272 views
in Technique[技术] by (71.8m points)

jakarta ee - Changing Java Timestamp format causes a change of the timestamp

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

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;
}

Output:

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

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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));

Result:

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

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

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

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.

Solution:

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));

Result:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...