4

I'm implementing functionality for formatting timestamps inserted in a database. An existing solution uses SimpleDateFormat for this task.
As SimpleDateFormat is not thread safe I'm converting the implementation to the use of java.time.

In this process I have bumped into some strange behavior where formating renders different results. The example below shows how a Timestamp is formatted as "1500-01-10 00:12:12" when using java.time and 1500-01-01 00:00:00 when using SimpleDateFormat.
I can not undertand why we are 9 day off when using java.time. Also where does the 12:12 come from.
The data is inserted into the database using '1500-01-01 00:00:00'.
Using the database formatting function DATE_FORMAT renders the expected output.

public static void main(String[] args) {
   // The following ts value is obtained by debugging the Timestamp
   // instance when reading data from MYSQL. 
   long ts = -14830995600000l;
   String TSPATTERN = "yyyy-MM-dd HH:mm:ss";
   Timestamp timestamp = new Timestamp(ts);
   System.out.println("                            ZoneId: " + ZoneId.systemDefault());
   System.out.println("timestamp.toString() " + timestamp);

   // java.time
   DateTimeFormatter f = DateTimeFormatter.ofPattern(TSPATTERN).withZone(ZoneId.systemDefault());
   String withJavaTime = f.format(timestamp.toInstant());

   // Using SimpleDate format
   SimpleDateFormat fdf = (SimpleDateFormat) SimpleDateFormat.getDateInstance();
   fdf.applyPattern(TSPATTERN);
   String withSDF = fdf.format(ts);
   System.out.println("       With java.time: " + withJavaTime);
   System.out.println("With SimpleDateFormat: " + withSDF);

   // Running the above will print the following output
   // Where does the 12:12 come from? and the 9 days?
   // With java.time: 1500-01-10 00:12:12
   // With SimpleDateFormat: 1500-01-01 00:00:00
}

I can also see a divergence when comparing the output from the database function DATE_FORMAT and JSR 310. Can that be explained by the database not taking in consideration ZoneOffsetTransition as done in JSR 310?

E.g formatting the timestamp corresponding to "1899-12-31 01:00:00" gives "1899-12-31 01:00:14" using the JSR 310. Listing the ZoneOffsetTransition for my (ZoneId Europe/Stockholm ) gives the following (Not complete list) which may explain the 14 minutes. Transition[Overlap at 1879-01-01T00:00+01:12:12 to +01:00:14] Transition[Overlap at 1900-01-01T00:00+01:00:14 to +01:00]

I tried to find a way to format the timestamp telling JSR 310 to skip using this data but have no success so far.

user1239974
  • 63
  • 1
  • 6
  • Thanks for the answer. I guess it boils down to not to use JSR 310 when you are dealing with data older than 1582. The function we are implementing is a general listing of database data. I guess that in most cases the users wants see the same data when entered in SQL and in a tool. Even though the actual timestamp in the database is wrong for cases like this. – user1239974 Oct 08 '17 at 10:57

1 Answers1

0

Instead of SimpleDateFormat you can use FastDateFormat which is thread safe.

Freiheit
  • 8,408
  • 6
  • 59
  • 101
  • 2
    The question isn't about alternatives to `SimpleDateFormat` - and it's also mentioned that the code is being migrated to `java.time` API (which is newer than `FastDateFormat` and also thread-safe as well), so this answer really doesn't address the issues mentioned in the question. –  Oct 06 '17 at 14:20