マシンに設定されているタイムゾーンに関係なく、時間に関連する操作をGMT / UTCに強制する必要があります。コードでそうするための便利な方法はありますか?
明確にするために、私はすべての操作にDBサーバー時間を使用していますが、ローカルのタイムゾーンに従ってフォーマットされています。
ありがとう!
マシンに設定されているタイムゾーンに関係なく、時間に関連する操作をGMT / UTCに強制する必要があります。コードでそうするための便利な方法はありますか?
明確にするために、私はすべての操作にDBサーバー時間を使用していますが、ローカルのタイムゾーンに従ってフォーマットされています。
ありがとう!
回答:
OPは、実行中のJVMの単一インスタンスのデフォルトのタイムゾーンを変更するには、この質問に答え、設定user.timezone
システムプロパティを:
java -Duser.timezone=GMT ... <main-class>
データベースからDate / Time / Timestampオブジェクトを取得するときに特定のタイムゾーンを設定する必要がある場合は、オブジェクトを取得するメソッドのResultSet
2番目の形式を使用します。getXXX
Calendar
Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
ResultSet rs = ...;
while (rs.next()) {
Date dateValue = rs.getDate("DateColumn", tzCal);
// Other fields and calculations
}
または、PreparedStatementで日付を設定します。
Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
PreparedStatement ps = conn.createPreparedStatement("update ...");
ps.setDate("DateColumn", dateValue, tzCal);
// Other assignments
ps.executeUpdate();
これらにより、データベース列にタイムゾーン情報が保持されていない場合でも、データベースに格納されている値の一貫性が保たれます。
java.util.Date
そしてjava.sql.Date
クラスは、UTCでの実際の時間(ミリ秒)を格納します。これらを出力時に別のタイムゾーンにフォーマットするには、を使用しますSimpleDateFormat
。Calendarオブジェクトを使用して、タイムゾーンを値に関連付けることもできます。
TimeZone tz = TimeZone.getTimeZone("<local-time-zone>");
//...
Date dateValue = rs.getDate("DateColumn");
Calendar calValue = Calendar.getInstance(tz);
calValue.setTime(dateValue);
便利なリファレンス
https://docs.oracle.com/javase/9/troubleshoot/time-zone-settings-jre.htm#JSTGD377
https://confluence.atlassian.com/kb/setting-the-timezone-for-the-java-environment-841187402.html
Windows 2003 Serverは常に新しいDate()に対してGMTを返すため、JVMタイムゾーンを設定する必要がありました。
-Duser.timezone=America/Los_Angeles
または、適切なタイムゾーン。タイムゾーンのリストを見つけるのも少し難しいことがわかりました...
ここに2つのリストがあります。
http://wrapper.tanukisoftware.com/doc/english/prop-timezone.html
TimeZone.setDefault()を使用してタイムゾーンを変更できます。
TimeZone.setDefault(TimeZone.getTimeZone("GMT"))
私にとっては、簡単なSimpleDateFormat、
private static final SimpleDateFormat GMT = new SimpleDateFormat("yyyy-MM-dd");
private static final SimpleDateFormat SYD = new SimpleDateFormat("yyyy-MM-dd");
static {
GMT.setTimeZone(TimeZone.getTimeZone("GMT"));
SYD.setTimeZone(TimeZone.getTimeZone("Australia/Sydney"));
}
次に、異なるタイムゾーンで日付をフォーマットします。
String sql = "SELECT CURRENT_TIMESTAMP ;
…
OffsetDateTime odt = myResultSet.getObject( 1 , OffsetDateTime.class ) ;
すべてのコードを記述して、希望する/予想されるタイムゾーンを明示的に示すことをお勧めします。JVMの現在のデフォルトのタイムゾーンに依存する必要はありません。また、JVMの現在のデフォルトのタイムゾーンは、実行中の任意の時点で、任意のアプリの任意のスレッド内の任意のコードで変更される可能性があることに注意してTimeZone.setDefault
ください。このような呼び出しは、そのJVM内のすべてのアプリにすぐに影響します。
他の回答のいくつかは正しかったが、現在は時代遅れです。Javaの最も初期のバージョンにバンドルされた恐ろしい日時クラスには欠陥があり、日時処理の複雑さと微妙さを理解していない人々によって書かれました。
従来の日時クラスは、JSR 310で定義されたjava.timeクラスに取って代わられました。
タイムゾーンを表すには、を使用しますZoneId
。UTCからのオフセットを表すには、を使用しますZoneOffset
。オフセットは、本初子午線の前後数時間分秒です。タイムゾーンははるかに大きいです。タイムゾーンは、特定の地域の人々が使用するオフセットに対する過去、現在、および将来の変更の履歴です。
時間関連の操作をGMT / UTCに強制する必要がある
ゼロ時分秒のオフセットには、定数を使用しZoneOffset.UTC
ます。
Instant
UTCで現在の瞬間をキャプチャするには、を使用しInstant
ます。このクラスは、定義により常にUTCであるUTCの瞬間を表します。
Instant instant = Instant.now() ; // Capture current moment in UTC.
ZonedDateTime
特定の地域の人々が使用する実時間を通じて同じ瞬間を確認するには、タイムゾーンに調整します。同じ瞬間、タイムライン上の同じポイント、異なる実時間。
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
あなたはデータベースについて言及しています。
データベースから瞬間を取得するには、列がSQL標準に似たデータ型である必要がありますTIMESTAMP WITH TIME ZONE
。文字列ではなくオブジェクトを取得します。JDBC 4.2以降では、java.timeオブジェクトをデータベースと交換できます。OffsetDateTime
一方で、JDBCによって必要とされるInstant
&ZonedDateTime
オプションです。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ほとんどのデータベースとドライバーでは、UTCで見られるような瞬間が得られると思います。ただし、そうでない場合は、次の2つの方法のいずれかで調整できます。
Instant
: odt.toInstant()
java.timeのフレームワークは、Java 8に組み込まれており、後にされています。これらのクラスは面倒古い取って代わるレガシーのような日付時刻クラスをjava.util.Date
、Calendar
、& SimpleDateFormat
。
詳細については、Oracleチュートリアルを参照してください。スタックオーバーフローで多くの例と説明を検索してください。仕様はJSR 310です。
ジョダタイムプロジェクトは、今でメンテナンスモードへの移行をアドバイスjava.timeのクラス。
java.timeオブジェクトをデータベースと直接交換できます。JDBC 4.2以降に準拠したJDBCドライバーを使用します。文字列もクラスも必要ありません。java.sql.*
java.timeクラスはどこで入手できますか?
システムプロパティを使用:
-Duser.timezone=UTC
intigerでのみGMT時間を取得したい場合:var currentTime = new Date(); var currentYear = '2010' var currentMonth = 10; var currentDay = '30 'var currentHours = '20' var currentMinutes = '20 'var currentSeconds = '00' var currentMilliseconds = '00 '
currentTime.setFullYear(currentYear);
currentTime.setMonth((currentMonth-1)); //0is January
currentTime.setDate(currentDay);
currentTime.setHours(currentHours);
currentTime.setMinutes(currentMinutes);
currentTime.setSeconds(currentSeconds);
currentTime.setMilliseconds(currentMilliseconds);
var currentTimezone = currentTime.getTimezoneOffset();
currentTimezone = (currentTimezone/60) * -1;
var gmt ="";
if (currentTimezone !== 0) {
gmt += currentTimezone > 0 ? ' +' : ' ';
gmt += currentTimezone;
}
alert(gmt)