Search code examples
javajdbctimezonetimestampmonetdb

Changing time zone after getting GMT time from database - MonetDB


I have MonetDB database with table containing user table:

CREATE TABLE user
(
    birth_date TIMESTAMP NOT NULL
);

birth_date is saved in GMT without DST. (This is the default behavior of MonetDB). So I should change the TimeZone in my application. Here is my code:

Class.forName("nl.cwi.monetdb.jdbc.MonetDriver");
Connection con = DriverManager.getConnection("jdbc:monetdb://localhost/online", "monetdb", "monetdb");      
Statement st = con.createStatement();
ResultSet rs;

rs = st.executeQuery("SELECT * FROM user");
while (rs.next()) {
    Calendar c = Calendar.getInstance(TimeZone.getTimeZone("Asia/Tehran"));
    c.setTime(rs.getTimestamp("birth_date"));
    System.out.println(c.get(Calendar.YEAR) + "-" + c.get(Calendar.MONTH) + "-" + c.get(Calendar.DAY_OF_MONTH) + " " + c.get(Calendar.HOUR_OF_DAY) + ":" + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND));
}

But this code print the same TIMESTAMP in the database. Is this the wrong way to convert TimeZone? I'm using MonetDB version 11.9.5-20120516 on Debian 6 with openjdk 6. Here is the monetdbd getall /home/dbfarm:

dbfarm           /home/dbfarm/
status           monetdbd[4187] 1.6 (Apr2012-SP1) is serving this dbfarm
mserver          /usr/bin/mserver5
logfile          /home/dbfarm//merovingian.log
pidfile          /home/dbfarm//merovingian.pid
sockdir          /tmp
port             50000
exittimeout      60
forward          proxy
discovery        yes
discoveryttl     600
control          yes
passphrase       {SHA512}ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413
mapisock         /tmp/.s.monetdb.50000
controlsock      /tmp/.s.merovingian.50000

Solution

  • Finally I got the answer.

    MonetDB runs in GMT by default and because Asia/Tehran was not available in database configuration so I need to convert time to Asia/Tehran time zone in my application. JVM takes its default TimeZone from OS and my OS was set to Asia/Tehran. So the program runs in Asia/Tehran by default and changing it to 'Asia/Tehran` again in code doesn't make any benefit. what I did was this:

    1. change the default TimeZone of JVM to UTC when application starts.
    2. retrieve record from database
    3. change TimeZone to Asia/Tehran

    Here is code:

    /* Change the default TimeZone of JVM */
    TimeZone.setDefault(TimeZone.getTimeZone("UTC")); 
    Calendar c = Calendar.getInstance();
    Class.forName("nl.cwi.monetdb.jdbc.MonetDriver");
    Connection con = DriverManager.getConnection("jdbc:monetdb://localhost/online", "monetdb", "monetdb");
    Statement st = con.createStatement();
    ResultSet rs;
    rs = st.executeQuery("SELECT * FROM user");
    /* In each iteration:
     * 1. set TimeZone to UTC
     * 2. fetch record
     * 3. convert to Asia/Tehran and so on ... */
    while (rs.next()) {
        c.setTimeZone(TimeZone.getTimeZone("UTC"));
        c.setTime(rs.getTimestamp("birth_date"));
        System.out.println(c); /* This is original values in the database */
        c.setTimeZone(TimeZone.getTimeZone("Asia/Tehran"));
        System.out.println(c); /* This is the values I'm looking for */
    }
    

    Note that without TimeZone.setDefault(TimeZone.getTimeZone("UTC")); this won't work. becuase JDBC has connected to database and converted the time to the default TimeZone of the JVM (which is Asia/Tehran in this case) before you can do any conversion.