web-dev-qa-db-ja.com

Java.time.ZoneIdにZoneIdのEnumが含まれていない理由はありますか?

ZoneIdを取得するには、次のようにします。

ZoneId.of("America/Sao_Paulo");

または

ZoneId.of(ZoneId.SHORT_IDS.get("BET"));

このような値のEnumが存在しない理由は次のとおりです。

ZoneId.of(ZoneIds.AMERICA_SAO_PAULO);

エラーが発生しにくく、オートコンプリートが使いやすいものはどれですか。

25
Renan

Javaバージョンに関係なく、可能なすべてのタイムゾーン名のリストが変更される可能性があるためです。

タイムゾーン情報 は、Java installation (通常、フォルダー_<Java-home>/lib/zi_、または新しいバージョンでは_jre/lib/tzdb.dat_ファイル)に含まれます)とともに表示されます。ただし、この情報は、Java versionTimezone Updater Toolを使用して)を変更せずに更新できます。 )。

タイムゾーンデータが更新され(ただしJavaバージョンは同じまま)、新しいゾーンIDが作成された場合、それに対応するEnumはなく、APIは「不完全」のままになります「そして、タイムゾーンデータ はJDKの更新よりも速く変更されます -そうでなかったとしても、本番環境でJDKのバージョンをいつでもすぐに更新できるとは限りません。

APIクリエーターの話をすることはできませんが、名前空間はJDKの更新よりも速く増加する可能性があり、列挙型を最新に維持することは無限で常にあるため、そのままにしておくことに決めたと思います不完全な仕事。

タイムゾーン名が有効かどうかを本当に確認したい場合は、次のようにします。

_if (ZoneId.getAvailableZoneIds().contains("America/Sao_Paulo")) {
    // America/Sao_Paulo is a valid ID
}
_

または、単にZoneId.of("zone-name")を呼び出してZoneRulesExceptionをキャッチします。


JDK 1.8.0_131ZoneId.getAvailableZoneIds()を呼び出したところ、600のエントリがあります。おそらく誰も600の列挙定数を作成したくありませんでした。

一部の言語(英語、ドイツ語、フランス語など)のエントリがいくつかある_Java.util.Locale_クラスと同様のことができたと主張することもできます。しかし、どのタイムゾーンが定数に「値する」かをどのように決定するのでしょうか?たぶん彼らはそれについてあまり考えないことに決めました、そして「ねえ、それを忘れて、ゾーン名でStringを使ってください」


もう1つの理由として、ZoneId.of()メソッドがUTCオフセット(_+05:00_、_-0300_、_+09:30:15_など)も受け取るように設計されていることが考えられます。オフセットは時間、分、秒を受け入れるので、数百の可能なオフセットがあり、それぞれに列挙型を作成することは現実的ではありません。

ここでも、「名前の列挙型だけを作成し、オフセットを忘れる」と主張できます。しかし、列挙名が作成されない可能性がある理由は、すでに上記で説明されています。

17
user7605325

JDKのタイムゾーンのセットは 完全に置換 にすることができます。そのため、ゾーンにenumを定義することはできません。

さらに、タイムゾーン識別子は比較的不安定です。それらは名前が変更され、マージされ、一般的に変更されます。 (私を含むさまざまな人々がIANAデータベースの安定性を高めようとしましたが、データベース管理者は同意しません。)

定数を提供する ThreeTen-ExtraZoneIdsクラスを作成するプルリクエストが検討されます。

7
JodaStephen

ZoneId#getAvailableZoneIds メソッドの説明が表示された場合、その理由はわかりますか?

このセットには、使用可能なすべてのリージョンベースIDの文字列形式が含まれています。オフセットベースのゾーンIDは、返されるセットに含まれません。 IDをof(String)に渡して、ZoneIdを作成できます。

ゾーンIDのセットは、時間とともに増加できますが、一般的なアプリケーションでは、IDのセットは固定されています。このメソッドの各呼び出しはスレッドセーフです。

5
holi-java