As far as I can tell there are two bugs involved here. Both are (if I am correct) in the java.util.Date
class, the superclass of java.sql.Timestamp
.
First, there is no time offset transition in Warsaw in year 1900. The earliest transition that my Java 8 knows of is in 1915. So Warsaw was at offset 1:24 from GMT during all of the time we’re concerned with.
I tried:
TimeZone.setDefault(TimeZone.getTimeZone("Europe/Warsaw"));
ZoneOffset offset0124 = ZoneOffset.ofHoursMinutes(1, 24);
System.out.println("" + new Date(0, 0, 1, 0, 59)
+ " -> " + new Date(0, 0, 1, 0, 59).toInstant().atOffset(offset0124));
System.out.println("" + new Date(0, 0, 1, 1, 14)
+ " -> " + new Date(0, 0, 1, 1, 14).toInstant().atOffset(offset0124));
System.out.println("" + new Date(0, 0, 1, 1, 24)
+ " -> " + new Date(0, 0, 1, 1, 24).toInstant().atOffset(offset0124));
This prints:
Mon Jan 01 00:59:00 CET 1900 -> 1900-01-01T01:23+01:24
Mon Jan 01 01:38:00 CET 1900 -> 1900-01-01T01:38+01:24
Mon Jan 01 01:24:00 CET 1900 -> 1900-01-01T01:24+01:24
The method Timestamp.valueOf
method that you use indirectly uses a deprecated Date
constructor, so so am I (not the exact same constructor, I am using the one without seconds, trusting it makes no difference). I will comment on the above three cases backward:
- 1:24 is handled correctly, we get the expected time both from
Date.toString()
and from the OffsetDateTime
.
- 1:14 is perceived as 1:38, 24 minutes later. This looks like a bug to me.
- 0:59 is perceived as 1:23, also 24 minutes later. We can see this from the
OffsetDateTime
. The same bug. However, Date.toString()
produces 00:59 as expected. This seems to me to be a second bug that somehow compensates for the first one. I haven’t checked, but I suspect that the source of this bug also causes Timestamp.toString()
to behave incorrectly.
As a check I calculated the difference between your Timestamp
objects of 0:59 and 1:24. The desired result is 25 minutes or 1 500 000 milliseconds. The code is:
System.out.println(java.sql.Timestamp.valueOf("1900-01-01 01:24:00").getTime()
- java.sql.Timestamp.valueOf("1900-01-01 00:59:00").getTime());
This prints
60000
60 seconds, the same as 1 minute. So even though both of those timestamps printed the way we had expected, there still is a bug involved.