Formatting timestamp using DateTimeFormatter for "early" dates

Viewed 3407

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.

1 Answers

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

Related