1

ユーザーテーブルを含むテーブルを持つMonetDBデータベースがあります。

CREATE TABLE user
(
    birth_date TIMESTAMP NOT NULL
);

birth_dateDSTなしでGMTで保存されます。(これはMonetDBのデフォルトの動作です)。したがってTimeZone、アプリケーションでを変更する必要があります。これが私のコードです:

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

しかし、このコードTIMESTAMPはデータベースに同じものを出力します。これは変換する間違った方法TimeZoneですか?私はopenjdk6を搭載したDebian6でMonetDBバージョン11.9.5-20120516を使用しています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

ついに答えが出ました。

MonetDBはGMTデフォルトで実行されますが、データベース構成では使用できなかったため、アプリケーションで時間をタイムゾーンにAsia/Tehran変換する必要があります。Asia/TehranJVMはTimeZoneOSからデフォルトを取り、私のOSはに設定されましたAsia/Tehran。したがって、プログラムはAsia/Tehranデフォルトで実行され、コードで再び「アジア/テヘラン」に変更しても何のメリットもありません。私がしたことはこれでした:

  1. TimeZoneJVMのデフォルトをUTCアプリケーションの起動時に変更します。
  2. データベースからレコードを取得する
  3. TimeZoneに変更Asia/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がデータベースに接続し、変換を実行する前に時間をデフォルトTimeZoneのJVM(Asia/Tehranこの場合)に変換したためです。

于 2012-05-28T04:26:12.217 に答える
1

monetdbから返される時間をどのように決定していますか?

Dateを使用するのではなく、を使用する次のコードを使用しました。これは、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 に答える