ZonedDateTime
とInstant.toEpochMilli()
の間で変換できるMIN/MAX時間値を使用して、フィルター/クエリのセンチネル値として使用したい。
私は試した:
OffsetDateTime.MIN.toInstant().toEpochMilli();
OffsetDateTime.MAX.toInstant().toEpochMilli();
しかし、私はこの例外を受け取ります:
Java.lang.ArithmeticException: long overflow
at Java.lang.Math.multiplyExact(Math.Java:892)
at Java.time.Instant.toEpochMilli(Instant.Java:1237)
そして私はこれを試しました:
ZonedDateTime.ofInstant(Instant.MIN, ZoneId.systemDefault());
ZonedDateTime.ofInstant(Instant.MAX, ZoneId.systemDefault());
しかし、私はこの例外を受け取ります:
Java.time.DateTimeException: Invalid value for Year (valid values -999999999 - 999999999): -1000000001
at Java.time.temporal.ValueRange.checkValidIntValue(ValueRange.Java:330)
at Java.time.temporal.ChronoField.checkValidIntValue(ChronoField.Java:722)
at Java.time.LocalDate.ofEpochDay(LocalDate.Java:341)
at Java.time.LocalDateTime.ofEpochSecond(LocalDateTime.Java:422)
at Java.time.ZonedDateTime.create(ZonedDateTime.Java:456)
at Java.time.ZonedDateTime.ofInstant(ZonedDateTime.Java:409)
私も 'Z' ZoneId
を試しました:
ZonedDateTime.ofInstant(Instant.MIN, ZoneId.of("Z"))
しかし、それは最後のものと同じ例外を返します。
最後に私は以下を試しました、そしてそれはうまくいくようです:
ZonedDateTime.ofInstant(Instant.Epoch, ZoneId.of("Z"));
ZonedDateTime.ofInstant(Instant.Epoch.plusMillis(Long.MAX_VALUE), ZoneId.of("Z"));
それが最善の解決策ですか?
_Instant.Epoch
_は_1970-01-01T00:00Z
_と同等であるため、最小値の候補として適切かどうかはわかりません(もちろん、ニーズによって異なります。すべての日付が1970以降の場合は、大丈夫です)。
_Instant.MIN
_および_Instant.MAX
_からZonedDateTime
への変換は、オフセットに応じて、フィールドが境界を超えた値に設定される可能性があるため、常に機能しません(たとえば、場合)。
ZonedDateTime
およびInstant
に変換できる遠い日付が必要な場合は、組み込みのMIN/MAX定数を使用する必要はありません。これは、(年から-1000000000〜1000000000など)、および同等のEpochミリこのような遠い日付の値は、long
値の制限よりもはるかに大きい(または小さい)です。
toEpochMilli()
を使用する必要があり、long
を返すため、long
値の範囲内に留まる必要があります。
_Instant minInstant = Instant.ofEpochMilli(Long.MIN_VALUE);
Instant maxInstant = Instant.ofEpochMilli(Long.MAX_VALUE);
ZonedDateTime minZonedDateTime = minInstant.atZone(ZoneOffset.UTC);
ZonedDateTime maxZonedDateTime = maxInstant.atZone(ZoneOffset.UTC);
_
それぞれの値は次のとおりです。
minInstant = -292275055-05-16T16:47:04.192Z
maxInstant = + 292278994-08-17T07:12:55.807Z
minZonedDateTime = -292275055-05-16T16:47:04.192Z
maxZonedDateTime = + 292278994-08-17T07:12:55.807Z
そして、エポックミリのそれぞれの値:
_System.out.println("minInstant millis=" + minInstant.toEpochMilli());
System.out.println("maxInstant millis=" + maxInstant.toEpochMilli());
_
minInstant millis = -9223372036854775808
maxInstant millis = 9223372036854775807
特定のタイムゾーンの代わりに_ZoneOffset.UTC
_を使用しました。これらの日付は過去/未来の遠い場所にあるため、数時間のオフセットでは大きな違いはありません。とにかく、それらはすべて同じミリ秒に相当します。
Instant
メソッド(minInstant.atOffset(ZoneOffset.UTC)
など)を使用して、OffsetDateTime
をatOffset
に変換することもできます。
メモ:
ZoneId.of("Z")
の代わりに、定数_ZoneOffset.UTC
_を使用できます。実際、ZoneId.of("Z").equals(ZoneOffset.UTC)
をチェックすると、結果はtrue
になります。ZoneId.of("Z") == ZoneOffset.UTC
でもtrue
でもあるので、どちらも同じものです。