8 JREでのタイムゾーン設定
この章の構成は、次のとおりです。
ネイティブ・タイムゾーン情報およびJRE
JREでは、デフォルト・タイムゾーンを判別するためにネイティブ・タイムゾーン情報を読み取ります。
たとえば、Windowsでは、JREはデフォルト・タイムゾーンを判別するためにレジストリを問い合わせます。
しかし、JREでは独自のタイムゾーン・データベースも保持しています。これにはクロスプラットフォーム・サポートが備わっていますが、その理由は様々なオペレーティング・システムのAPIがJava APIをサポートするのに不十分であるからです。Javaタイムゾーン・データベースは、タイムゾーンIDをサポートし、JREがサポートしているすべてのタイムゾーンの夏時間ルールを決めます。tzupdater
ツールは、Java SEダウンロード・ページからダウンロードして使用できます。
オペレーティング・システムがシステム時間をJREに配信できるように、JREへの変更をオペレーティング・システムごとに行う必要があります。その後、Javaアプリケーションが日付と時間に関連したコンストラクタを呼び出してシステム日付を要求すると、システム時間が返されます。
そのようなコンストラクタの例を次に示します。
- java.util.Date()
- java.util.GregorianCalendar()
日付と時間に関連したコンストラクタには、次が含まれています。
- System.currentTimeMillis()
- System.nanoTime()
正しいシステム時間が必ずJREに配信されるようにするには、オペレーティング・システム固有のパッチが必要になる場合があります。
次の項では、タイムゾーンの設定のトラブルシューティング手法について説明します。
使用中のタイムゾーン・データ・バージョンの判別
Oracle提供のJREに付属しているタイムゾーン・データベースのバージョンは、リリース・ノートに記載されています。ただし、tzupdater
ツールを使用してJREにパッチを適用した場合は、実際のバージョンがそこに記載されているバージョンと異なることがあります。
使用しているJREの現在のタイムゾーン・データ・バージョンを判別するには、Versionオプションを指定してtzupdater
ツールを実行するか、ZoneInfoMappings
ファイルのヘッダーを調べます。
タイムゾーン・データを確認するには、これらの2つの手順に従います。
-
TZupdaterによるタイムゾーンの確認: Javaのタイムゾーン更新ツールは
tzupdater
と呼ばれています。使用しているJREのタイムゾーン・データベース・バージョンを判別するには、このツールを次のように実行します。java -jar tzupdater.jar -V
tzupdater
ツールの実行による標準的な出力を次に示します。tzupdater version 2.1.0-b04 JRE tzdata version: tzdata2016f
tzupdater
ツールは、Timezone Updater ToolというWebページからダウンロードできます。 -
ZoneInfoMappingsファイルの確認:
tzupdater
ツールがない場合でも、<java-home>/lib/zi/ZoneInfoMappings
ファイルのヘッダーを調べることでバージョンをすぐに確認できます。このデータは、Javaに固有のバイナリ・フォーマットで保存されます。Oracle Solaris、LinuxおよびmacOSオペレーティング・システムでは、8進数のダンプ・コマンドを使用してこのファイルのヘッダーを調べることができます。次の例に、8進数ダンプ・コマンド形式を示します。
/usr/bin/od -c -j 11 -N 11 <java-home>/lib/zi/ZoneInfoMappings
次に、dumpコマンドの一般的な結果を示します。
/usr/bin/od -c -j 11 -N 11 /farfaraway/jdks/jdk1.6.0_21/jre/lib/zi/ZoneInfoMappings0000000 t z d a t a 2 0 1 0 i0000013
次の例は、このJREに埋め込まれているタイムゾーン・データのバージョンが
tzdata2010i
であることを示しています。Microsoft Windowsでは、
findstr
コマンドを使用してZoneInfoMappings
ファイルを調べることができます。次に例を示します。findstr tzdata <java-home>\lib\zi\ZoneInfoMappings
Tzupdaterの問題のトラブルシューティング
tzupdater
の実行時に、それが「このJavaランタイムで使用できるタイムゾーン・データはありません」というメッセージを表示して終了することがときどきあります。次に2つの例を示します。
$ java -jar tzupdater.jar -V
tzupdater version 2.1.1-b01
JRE tzdata version: tzdata2017b
There's no tzdata available for this Java runtime.
考えられる原因は、Oracle提供でないJREを使用していることです。Oracleが提供するJREは、Oracle Solaris (x86、x64、SPARC)、Linux (x86、x64、ARM)、Microsoft Windows (x86、x64)、およびmacOS (x64)用です。これらのJREのjava.vendor
プロパティ値はSun Microsystems Inc.、Oracle Corporation、またはBEA Systems, Inc.です。Oracleでは、それ以外のプラットフォーム用のJREを提供していません。
java -version
コマンドを実行した場合の出力は、JREの実際のベンダーを判断するのに十分な情報を提供しません。しかし、-v
オプションを指定してtzupdater
を更新モードで実行すると、java.vendor
プロパティが出力されます。次の例に、環境がHewlett PackardのHP_UXである場合のtzupdaterの実行結果を示します。
root@my_server:/opt/java6/bin> uname -a
HP-UX my_server B.11.23 U ia64 1114591084 unlimited-user license
root@my_server:/opt/java6/bin> ./java -version
java version "1.6.0.05"
Java(TM) SE Runtime Environment (build 1.6.0.05-jinteg_14_oct_2009_01_44-b00)
Java HotSpot(TM) Server VM (build 14.2-b01-jre1.6.0.05-rc5, mixed mode)
root@my_server:/opt/java6/bin> ./java -jar tzupdater.jar -v -l
java.home: /opt/java6/jre
java.vendor: Hewlett-Packard Co.
java.version: 1.6.0.05
JRE tzdata version: tzdata2009i
There's no tzdata available for this Java runtime.
前の例では、java.vendor
が「Hewlett-Packard Co.」に設定されています。tzupdater
を使用して更新を試みているJREはOracleでサポートされていません。
考えられる解決方法は、使用しているJREベンダーのWebサイトを参照して、使用可能なタイムゾーン更新ツールがあるかどうかを確認することです。
Windowsでのデフォルト・タイムゾーンの判別
このセクションでは、Windows VistaおよびWindows 7オペレーティング・システムでJREがデフォルト・タイムゾーンを判別する方法について明確に説明します。Javaが期待されたタイムゾーンを報告しない場合は、次の各セクションで説明するトラブルシューティング方法を使用してください。
JREが報告するデフォルト・タイムゾーンの確認
ネイティブ・オペレーティング・システムによるチェックに基づいて、JREがデフォルト・タイムゾーンとして報告するタイムゾーンを確認するための簡単なプログラムを作成できます。
次の例のJavaプログラムはデフォルト・タイムゾーンを返します。
public class DefaultTimeZone { public static void main(String[] args) { System.out.println(java.util.TimeZone.getDefault().getID()); } }
前の例のコード・スニペットをDefaultTimeZone.java
という名前のファイルに保存し、javac
コマンドを使用してコンパイルできます。次に、次の例に示すように、コンパイルしたDefaultTimeZone
クラスを実行できます。
c:\tztest> javac DefaultTimeZone.java c:\tztest> java DefaultTimeZone Europe/Berlin
前の例では、デフォルト・タイムゾーンはEurope/Berlinです。プログラムを実行すると、ローカル・タイムゾーンが表示されるはずです。出力が予期されたタイムゾーンでない場合は、次のトラブルシューティング手順を続けて実行してください。
コントロール・パネルでの設定の確認
Windowsコントロール・パネルを使用して、システムのデフォルト・タイムゾーンを変更または確認できます。たとえば、Windows 7で次のタイムゾーン設定を選択できます。
(UTC+01:00)アムステルダム、ベルリン、ベルン、ローマ、ストックホルム、ウィーン
対応するTimeZoneKeyName
レジストリ・キーの値は、西ヨーロッパ標準時間です。
夏時間の自動調整の確認
グラフィカル・ユーザー・インタフェース(GUI)またはWindowsレジストリを通じて、夏時間の自動調整が有効かどうかを確認できます。
-
GUIによる方法: コントロール パネルを使用して夏時間の自動調整が有効かどうかを確認するには:
-
Windowsの「スタート」ボタン、「コントロール パネル」の順にクリックします。
-
「日付と時刻」をクリックします。
-
「タイム ゾーンの変更」ボタンをクリックします。
-
「自動的に夏時間の調整をする」というラベルの付いたチェック・ボックスが表示されます。このチェック・ボックスが選択されているかどうかを確認し、必要に応じて設定を変更します。
-
「OK」をクリックします。「日付と時刻」ダイアログ・ボックスに戻ります。
-
-
Windowsレジストリによる方法: Windowsレジストリ・エディタを実行して夏時間の自動調整が有効かどうかを確認できます。
注意:
Windowsレジストリを確認または編集する前にバックアップを取っておくことをお薦めします。間違った操作をすると、Windowsレジストリが損なわれる可能性があります。
Windowsレジストリから夏時間の自動調整を有効にするには:
-
Windowsの「スタート」ボタンをクリックします。
-
「プログラムとファイルの検索」フィールドで、「regedit」と入力してから[Enter]キーを押して、レジストリ・エディタを開きます。
-
レジストリ・エディタで、DynamicDaylightTimeDisabledというキーを探し、その設定を調べます。
レジストリ設定が1の場合、動的な夏時間は無効になっています。
レジストリ設定が0の場合、動的な夏時間は有効になっています。
お好みで、Windowsコマンド・ウィンドウからWindowsレジストリにアクセスすることもできます。
-
次の例では、レジストリ設定は1です。この設定では、時計は夏時間に合わせて自動的に調整されません。
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation] "DynamicDaylightTimeDisabled"=dword:00000001
DynamicDaylightTimeDisabled
オプションを無効にした場合、JavaはGMT (グリニッチ標準時間)オフセットを返し、統一されたネーミング規則と互換性のあるタイムゾーンID(「Europe/Berlin」など)を返しません。たとえば、このオフセットは「Europe/Berlin」ではなくGMT+01として表されます。
コントロール・パネルでのデフォルト・タイムゾーンの設定
Windowsコントロール パネルを使用して、システムのデフォルト・タイムゾーンを変更または確認できます。
コントロール・パネルからシステムのデフォルト・タイムゾーンを設定するには:
- Windowsの「スタート」ボタン、「コントロール パネル」の順にクリックします。
- 「日付と時刻」をクリックします。
- 「タイム ゾーンの変更」ボタンをクリックします。
- 「タイム ゾーン」メニューから、希望するタイムゾーンを選択します。
- 「OK」をクリックします。「日付と時刻」ダイアログ・ボックスに戻ります。
- 「OK」をクリックして「日付と時刻」ダイアログ・ボックスを閉じます。
たとえば、Windows 7で次のタイムゾーンを選択できます。
(UTC)+1:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna.
対応するTimeZoneKeyName
レジストリ・キーの値は、西ヨーロッパ標準時間です。
-Duser.timezoneシステム・プロパティの確認
user.timezone
と呼ばれるJavaシステム・プロパティを使用することにより、コマンド行でデフォルト・タイムゾーンを明示的に設定できます。これにより、Windowsオペレーティング・システムでの設定が省略され、回避方法となることもあります。たとえば、システム上で実行されている1つのJavaプログラムでのみ夏時間(DST)を適用する場合にこの設定が役立ちます。
次の例では、Windowsの「コマンド プロンプト」ウィンドウからDefaultTimeTestZoneと呼ばれるJavaプログラムを実行することで、-Duser.timezone
システム・プロパティを表示します。
c:\tztest> java -Duser.timezone=America/New_York DefaultTimeZone America/New_York
-Duser.timezone
を指定することでデフォルト・タイムゾーンを明示的に設定することがDefaultTimeTestZone
プログラムには有効だが、使用しているプログラムには有効でない場合、実行時に次のようなメソッド呼出しを使用してコードがデフォルトのJavaタイムゾーンを上書きするかどうかを確認するようにしてください。
TimeZone.setDefault(TimeZone zone)
Windows 7の特別なツール
Windows 7では、tzutil.exe
と呼ばれるツールを使用できます。このツールを使用すると、手動でレジストリを確認することなく、現在のタイムゾーンIDの略称を要求できます。
tzutil.exe
の実行例を次に示します。最初の行は、Windowsの「コマンド プロンプト」ウィンドウで入力するコマンドです。2番目の行はシステム・レスポンスです。
tzutil /g W. Europe Standard Time
タイムゾーン・マッピングのJRE内部表現
Windowsでは、JREは<java-home>\lib\tzmappings
ファイルを使用してWindowsタイムゾーンとJavaタイムゾーンのマッピングを表現します。このファイルの各行には4つのトークンがあります。最初のトークンは、TimeZoneKeyName
と呼ばれるWindowsタイムゾーンのレジストリ・キーです。「コントロール・パネルでの設定の確認」を参照してください。
2番目のトークンは、タイムゾーン・マップIDです。(これはWindows VistaおよびWindows 7では使用されません。)3番目のトークンはロケールです。4番目のトークンはJavaタイムゾーンIDを表しています。重要なトークンは、1番目、3番目(空の場合もある)、および4番目のトークンです。(注意: このファイルはパブリック・インタフェースではありません。)
Windowsのコントロール パネルで「(UTC+01:00)アムステルダム、ベルリン、ベルン、ローマ、ストックホルム、ウィーン」と呼ばれるタイムゾーンを選択した場合、tzmappings
ファイルの関連する行は次のようになります。
W. Europe Standard Time:2,3::Europe/Berlin:
この例では、JREはデフォルトのタイムゾーン(4番目のトークン)を「Europe/Berlin」と認識します。
tzmappingsファイルに適切なマッピング・エントリが存在しない場合、MicrosoftがWindows更新で新しいタイムゾーンを導入したが、その新しいタイムゾーンがJREで使用できない可能性があります。この場合、JREのバグ・レポートを提出し、オラクルのJavaバグWebサイトからtzmappingsファイルの新しいエントリを要求できます。
tzedit.exe
ツールを実行すると、オペレーティング・システムとJREの間で同様の切断が発生する可能性があります。このツールはMicrosoftによってインターネットに投稿されており、ユーザーが新しいタイム・ゾーンを追加できます。JREで、このツールによってタイムゾーンがシステムに導入される可能性はありません。この場合も、解決方法はバグを提出して、新しいエントリがtzmappings
ファイルに追加されるように要求することです。