Question

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
Was it helpful?

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.

OTHER TIPS

How are you determining the time as returned from the monetdb?

I used the following code, which uses a Date, rather than an java.sql.Timestamp, and it appropriately converts from one timezone to another, so is it possible that something is translating the time from UTC to the localtime for you automatically?

    Date d = new Date();
    Calendar c = Calendar.getInstance(TimeZone.getTimeZone("Asia/Tehran"));
    c.setTime(d);
    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));
    c.setTimeZone(TimeZone.getTimeZone("UTC"));
    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));

Edit If your java is badly configured, trying to get the timezone can fail; yielding the output in the same timezone as GMT, so you should always make sure that you're getting the correct timezone

TimeZone tz = TimeZone.getTimeZone("Asia/Tehran");
System.out.println(tz.toString());

Displays sun.util.calendar.ZoneInfo[id="Asia/Tehran",offset=12600000,dstSavings=3600000,useDaylight=true,transitions=100,lastRule=java.util.SimpleTimeZone[id=Asia/Tehran,offset=12600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=1,startMonth=2,startDay=21,startDayOfWeek=0,startTime=0,startTimeMode=0,endMode=1,endMonth=8,endDay=21,endDayOfWeek=0,endTime=0,endTimeMode=0]] for me; while:

TimeZone tz = TimeZone.getTimeZone("Asia/fred");
System.out.println(tz.toString());

Displays sun.util.calendar.ZoneInfo[id="GMT",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top