1

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
4

2 回答 2

4

最后我得到了答案。

MonetDBGMT默认运行,因为Asia/Tehran在数据库配置中不可用,所以我需要Asia/Tehran在我的应用程序中将时间转换为时区。JVM 采用操作系统的默认值TimeZone,我的操作系统设置为Asia/Tehran. 因此,该程序Asia/Tehran默认运行并在代码中再次将其更改为“亚洲/德黑兰”并没有任何好处。我所做的是:

  1. TimeZone将JVM的默认值更改为UTC应用程序启动时。
  2. 从数据库中检索记录
  3. 更改TimeZoneAsia/Tehran

这是代码:

/* 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 */
}

请注意,没有TimeZone.setDefault(TimeZone.getTimeZone("UTC"));这个是行不通的。因为 JDBC 已经连接到数据库并将时间转换为TimeZoneJVM 的默认值(Asia/Tehran在这种情况下),然后您才能进行任何转换。

于 2012-05-28T04:26:12.217 回答
1

您如何确定从 monetdb 返回的时间?

我使用了以下代码,它使用 a Date,而不是 a java.sql.Timestamp,并且它适当地从一个时区转换为另一个时区,那么是否有可能自动将时间从 UTC 转换为本地时间?

    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));

编辑如果您的 java 配置错误,尝试获取时区可能会失败;在与 GMT 相同的时区产生输出,因此您应始终确保获得正确的时区

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

为我展示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]];尽管:

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

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

于 2012-05-27T10:32:04.443 回答