pgjdbc/pgjdbc GitHub issues and pull requests (mirror)  
help / color / mirror / Atom feed
From: m-van-tilburg (@m-van-tilburg) <[email protected]>
To: pgjdbc/pgjdbc <[email protected]>
Subject: Re: [pgjdbc/pgjdbc] issue #3837: ResultSet.getTimestamp() returns incorrect point in time for historical dates
Date: Mon, 13 Oct 2025 11:45:56 +0000
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
References: <[email protected]>

> his issue seems unrelated to JDBC. I observed that `TIMESTAMP_LOCAL_1000_AD` is already incorrect. It also seems to be caused by JDK behavior.

You are correct that the issue is not in the JDBC API itself, the created point in time in the test code is correct however. You can verify this by inputting the value of `TIMESTAMP_LOCAL_1000_AD.getTime()` into a website like https://www.epochconverter.com/.

I suspect you came to your conclusion because you saw the the result of `Timestamp.toString()` in your debugger, which will interpret this (historic) point in time using the Julian calendar. `java.util.Date` and `java.sql.Timestamp` store points in time just like `java.time.Instant`, the important part is how these points in time are parsed/formatted from/to actual calendar dates. The following additional code using the legacy `java.util.Calendar` class demonstrates this:

```
  @Test
  void legacyCalendarExamples() {
    // NOTE: it may appear this creates a (proleptic) Gregorian calendar but for historic dates it is Julian!
    GregorianCalendar calGregorianJulianHybrid = new GregorianCalendar();
    calGregorianJulianHybrid.setTime(TIMESTAMP_LOCAL_1000_AD);
    System.out.println("Julian calendar date and time: " + formatCalendar(calGregorianJulianHybrid));

    GregorianCalendar calProlepticGregorian = new GregorianCalendar();
    // This will make the calendar pure (proleptic) Gregorian
    calProlepticGregorian.setGregorianChange(new Date(Long.MIN_VALUE));
    calProlepticGregorian.setTime(TIMESTAMP_LOCAL_1000_AD);
    System.out.println("(proleptic) Gregorian calendar date and time: " + formatCalendar(calProlepticGregorian));
  }

  private String formatCalendar(Calendar cal) {
    // NOTE: Calendar.MONTH is zero based
    return cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-" + cal.get(Calendar.DAY_OF_MONTH) + "T" +
      cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE) + ":" + cal.get(Calendar.SECOND);
  }
```

On my system with time zone set to "Europe/Amsterdam" this produces the following result:

Julian calendar date and time: 999-12-27T0:42:30
(proleptic) Gregorian calendar date and time: 1000-1-1T0:42:30

Note that although `java.util.GregorianCalendar` by default uses the system default time zone the results are not always identical to when `java.time.ZonedDateTime` with the system default time zone is used. The reason for this is that the time zone rule handling for historical dates can be different between `java.util.TimeZone` and `java.time`.

view thread (13+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: github://pgjdbc/pgjdbc
  Cc: [email protected], [email protected]
  Subject: Re: [pgjdbc/pgjdbc] issue #3837: ResultSet.getTimestamp() returns incorrect point in time for historical dates
  In-Reply-To: <<[email protected]>>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox