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
해결책
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:
- change the default
TimeZone
of JVM toUTC
when application starts. - retrieve record from database
- change
TimeZone
toAsia/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.
다른 팁
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]