jOOQ seems to apply the current system timezone when selecting Postgres Timestamp With Timezone, but indicates the return as UTC

喜夏-厌秋 提交于 2019-12-02 18:46:32

问题


Simple test inserting a serial id and a timestamp with timezone then selecting the data back. The value returned is in my local time but is indicated as UTC. Below are raw selects from Postgres and corresponding values in Java as queried via jOOQ.

set timezone to 'UTC';
select * from date_tests;
 id |     test_timestamp     
----+------------------------
  1 | 2019-05-30 17:54:32+00

set timezone to 'America/Denver';
SET
select * from date_tests;
 id |     test_timestamp     
----+------------------------
  1 | 2019-05-30 11:54:32-06

When querying Postgres, it tells me what time zone the Instant has been converted to. When I get the same responses in Java, the Instant is converted to whatever time the JVM is set to, but the offset is NOT set accordingly. Example below. I believe I would classify this as a jOOQ bug.

        TimeZone.setDefault( TimeZone.getTimeZone( "UTC" ) );
        DateTestsRecord insertedRecord = context.selectFrom( DATE_TESTS ).where( DATE_TESTS.ID.eq( id ) ).fetchAny();
        System.out.println( insertedRecord.getTestTimestamp() );
//Output is 2019-05-30T17:54:32Z
//Makes sense, the inserted timestamp was hour 17 UTC

        TimeZone.setDefault( TimeZone.getTimeZone( "America/Denver" ));
        DateTestsRecord insertedRecordInMountain = context.selectFrom( DATE_TESTS ).where( DATE_TESTS.ID.eq( id ) ).fetchAny();
        System.out.println( insertedRecordInMountain.getTestTimestamp() );
//Output is 2019-05-30T11:54:32Z
//Makes NO sense, the hour was 17 UTC, either give it to me as 17 Z
//Or convert to -6 because my system time is Mountain, 
//but indicate it has a -6 offset.  
//But don't give a -6 time and say it's Z.  

Once again, this seems to have nothing to do with what time the database is set to, depends only on the default time set with TimeZone.setDefault.

Original test code and discussion at jOOQ returns offset date time as Z (UTC) even though it's not

More info after debugging:

After stepping through the jOOQ code for a while, I believe I found the culprit. In DefaultBinding.java:

    else if (type == OffsetDateTime.class) {
        result = (T) offsetDateTime(ctx.resultSet().getString(ctx.index()));
    }

If I call getObject here, I find the object at index 2 (the test_timestamp) is a java.sql.Timestamp. The toString value of this object is the "2019-05-30 11:54:32.0" without the offset, but clearly with the offset applied (look at postgres output above, hour 11 is with a -6 offset). If I call getObject, I can see that the expected offset is stored, but not properly returned using the default toString. I'm on Java 1.8.0_211-b12. I don't know if this toString behavior has changed over time.

Continuing from there, I see the OffsetDateTime parse method comments indicate this string was expected to contain the offset, which seems obvious. No way to invent the correct offset if the string does not contain it, which it does not thanks to the Timestamp toString behavior I discuss above.

来源:https://stackoverflow.com/questions/57808703/jooq-seems-to-apply-the-current-system-timezone-when-selecting-postgres-timestam

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!