Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

postgresql JDBC driver uses client time zone

I am using postgresql-42.2.2.jar jdbc driver and postgresql 9.6 server.

How can I configure the connection to use server timezone instead of client timezone?

Query:

select id, TO_TIMESTAMP(tbl.ended_time / 1000)
FROM tbl
where TO_TIMESTAMP(tbl.ended_time / 1000) >= now()::date + interval '1m'

Running a query with pgadmin I am getting the following result (which is correct)

"2185"  "2018-06-22 00:02:02-05"
"2186"  "2018-06-22 00:03:01-05"
"2187"  "2018-06-22 00:13:02-05"

but running the same query with JDBC driver the result is :

2169 2018-06-22 07:13:01.0
2181 2018-06-22 08:33:02.0
2180 2018-06-22 08:23:01.0
2185 2018-06-22 09:02:02.0
2186 2018-06-22 09:03:01.0
2187 2018-06-22 09:13:02.0

without where the running query with pgadmin the result is:

"2169"  "2018-06-21 22:13:01-05"
"2181"  "2018-06-21 23:33:02-05"
"2180"  "2018-06-21 23:23:01-05"
"2185"  "2018-06-22 00:02:02-05"
"2186"  "2018-06-22 00:03:01-05"
"2187"  "2018-06-22 00:13:02-05"

Here is the code:

static String URL = "jdbc:postgresql://some_ip:7000/db";
static String USERNAME = "test";
static String PASSWORD = "test";
static String JDBC_DRIVER = "org.postgresql.Driver";

public static void main(String[] args) {
    String query = "select id, TO_TIMESTAMP(tbl.ended_time / 1000) FROM tbl where TO_TIMESTAMP(tbl.ended_time / 1000) >= now()::date + interval '1m'";
    Connection conn = null;

    try {
        Class.forName(JDBC_DRIVER);
        conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
        Statement st = conn.createStatement();          
        ResultSet rs = st.executeQuery(query);
        while (rs.next()) {             
            System.out.println(rs.getObject(1) + "--" + rs.getObject(2));
        }
        rs.close();
        st.close();
        conn.close();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 

}
like image 562
Lusi Avatar asked Jun 25 '26 13:06

Lusi


1 Answers

As explained here, the JDBC driver uses your local time zone and not the server time zone.

Unfortunately there is no easy way to change that behaviour or to query the server's time zone.

Also note that retrieving the data using an OffsetDateTime doesn't help much:

rs.getObject(2, OffsetDateTime.class)

because unfortunately, the driver returns all OffsetDateTimes with an offset of 0, so the timezone information is lost.

So it seems that your best bet is probably to either hardcode the database's timezone and calculate your time limit in Java or to store the timezone separately in your DB and query it.

like image 72
assylias Avatar answered Jun 27 '26 02:06

assylias