一時的なクエリ
java.timeフレームワークよりもあまり短くなってしまうでしょう含まれている場合、あなたはまだそれを伝える必要があります日付時刻値:Temporal QueryTemporalQuery
インターフェイスのいくつかの実装は、複数の名前のTemporalQueries
クラスにあります。
独自の実装も作成できます。 TemporalQuery
はfunctional interfaceであり、単一のメソッドが宣言されていることを意味します。方法はqueryFrom
です。
の実装時に私が最初に試したのはなので、塩の粒をとってください。ここには完全なクラスがあります。無料(ISC License)を使用することができますが、完全に自己責任で行ってください。
難しい部分は、渡された日時値のタイムゾーンまたはオフセットではなく、週末がUTCで定義されるという質問です。だから渡された日時の値をUTCに調整する必要があります。 Instant
は論理的には同等ですが、はoffset of UTCと柔軟性があります。具体的にはOffsetDateTime
にはgetDayOfWeek
メソッドがあります。
CAVEAT:私はオーソドックスな方法で物事をやっている場合は、その作成者が意図したとおり、私は完全にjava.timeのデザインの基盤を理解していないとして、私は見当がつかない。具体的には、TemporalAccessor ta
からjava.time.chrono.ChronoZonedDateTime
へのキャスティングが適切かどうかはわかりません。しかし、それは十分にうまくいくようです。
このクラスがInstant
のインスタンスだけでなく、ChronoZonedDateTime
/ZonedDateTime
のインスタンスで動作するとよいでしょう。
package com.example.javatimestuff;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
/**
* Answers whether a given temporal value is between Friday 22:00 UTC
* (inclusive) and Sunday 23:00 UTC (exclusive).
*
* @author Basil Bourque.
*
* © 2016 Basil Bourque
* This source code may be used according to the terms of the ISC License (ISC). (Basically, do anything but sue me.)
* https://opensource.org/licenses/ISC
*
*/
public class WeekendFri2200ToSun2300UtcQuery implements TemporalQuery<Boolean> {
static private final EnumSet<DayOfWeek> WEEKEND_DAYS = EnumSet.of (DayOfWeek.FRIDAY , DayOfWeek.SATURDAY , DayOfWeek.SUNDAY);
static private final OffsetTime START_OFFSET_TIME = OffsetTime.of (LocalTime.of (22 , 0) , ZoneOffset.UTC);
static private final OffsetTime STOP_OFFSET_TIME = OffsetTime.of (LocalTime.of (23 , 0) , ZoneOffset.UTC);
@Override
public Boolean queryFrom (TemporalAccessor ta) {
if ( ! (ta instanceof java.time.chrono.ChronoZonedDateTime)) {
throw new IllegalArgumentException ("Expected a java.time.chrono.ChronoZonedDateTime such as `ZonedDateTime`. Message # b4a9d0f1-7dea-4125-b68a-509b32bf8d2d.");
}
java.time.chrono.ChronoZonedDateTime czdt = (java.time.chrono.ChronoZonedDateTime) ta;
Instant instant = czdt.toInstant();
OffsetDateTime odt = OffsetDateTime.ofInstant (instant , ZoneOffset.UTC);
DayOfWeek dayOfWeek = odt.getDayOfWeek();
if ( ! WeekendFri2200ToSun2300UtcQuery.WEEKEND_DAYS.contains (dayOfWeek)) {
// If day is not one of our weekend days (Fri-Sat-Sun), then we know this moment is not within our weekend definition.
return Boolean.FALSE;
}
// This moment may or may not be within our weekend. Very early Friday or very late Sunday is not a hit.
OffsetDateTime weekendStart = odt.with (DayOfWeek.FRIDAY).toLocalDate().atTime (START_OFFSET_TIME); // TODO: Soft-code with first element of WEEKEND_DAYS.
OffsetDateTime weekendStop = odt.with (DayOfWeek.SUNDAY).toLocalDate().atTime (STOP_OFFSET_TIME); // TODO: Soft-code with last element of WEEKEND_DAYS.
// Half-Open -> Is equal to or is after the beginning, AND is before the ending.
// Not Before -> Is equal to or is after the beginning.
Boolean isWithinWeekend = ( ! odt.isBefore (weekendStart)) && (odt.isBefore (weekendStop));
return isWithinWeekend;
}
static public String description() {
return "WeekendFri2200ToSun2300UtcQuery{ " + START_OFFSET_TIME + " | " + WEEKEND_DAYS + " | " + STOP_OFFSET_TIME + " }";
}
}
TemporalQuery
としましょう。TemporalQuery
を定義すること、それはとてもシンプルで簡単です使用して、いくつかの作業を取りながら:
TemporalQuery
オブジェクトをインスタンス化します。
- 日時オブジェクトに適用します。
使用において
(我々の場合でjava.time.chrono.ChronoZonedDateTime
の任意のインスタンス、例えばZonedDateTime
など)。
WeekendFri2200ToSun2300UtcQuery query = new WeekendFri2200ToSun2300UtcQuery();
私は、クエリの設定を確認するには、デバッグとロギング用の静的description
方法を追加しました。これは私自身の発明方法であり、TemporalQuery
インターフェイスでは必要ありません。
System.out.println ("Weekend is: " + WeekendFri2200ToSun2300UtcQuery.description());
最初の今日、火曜日。週末にはいけません。
ZonedDateTime now = ZonedDateTime.now (ZoneId.of ("America/Montreal"));
Boolean nowIsWithinWeekend = now.query (query);
System.out.println ("now: " + now + " is in weekend: " + nowIsWithinWeekend);
今週金曜日の午前です。 ではなく、が週末になるはずです。
ZonedDateTime friday1000 = ZonedDateTime.of (LocalDate.of (2016 , 4 , 29) , LocalTime.of (10 , 0) , ZoneId.of ("America/Montreal"));
Boolean friday1000IsWithinWeekend = friday1000.query (query);
System.out.println ("friday1000: " + friday1000 + " is in weekend: " + friday1000IsWithinWeekend);
遅くとも今週の金曜日です。週末にはTRUEにする必要があります。
ZonedDateTime friday2330 = ZonedDateTime.of (LocalDate.of (2016 , 4 , 29) , LocalTime.of (23 , 30) , ZoneId.of ("America/Montreal"));
Boolean friday2330IsWithinWeekend = friday2330.query (query);
System.out.println ("friday2330: " + friday2330 + " is in weekend: " + friday2330IsWithinWeekend);
実行時。
週末:WeekendFri2200ToSun2300UtcQuery {22:00Z | [FRIDAY、SATURDAY、SUNDAY] | 23:00Z}
今:2016-04-26T20:35:01.014から04:00 [アメリカ/モントリオール]週末である:偽
friday1000:2016-04-29T10:00から04:00 [アメリカ/モントリオール]週末である:偽
friday2330:2016-04-29T23:30-04:00 [アメリカ/モントリオール]週末である:真
Local…
は、ローカル
を意味するものではありません
質問を参照する...あなたがcにしたいと言っているLocalDateTime
をUTC(週末の開始/停止)の値に変更することは意味がありません。 LocalDateTime
には、UTCからのオフセットのタイムゾーンはありません。命名は直感的ではないかもしれませんが、Local…
クラスは、特にローカリティのない地域に適用できることを意味します。だから、彼らは意味がありません、あなたは指定されたオフセットやタイムゾーンを適用するまで、タイムライン上のポイントではありません。
この全体の回答は、この用語について混乱し、タイムライン上の実際の瞬間を比較しようとしていたことを前提としています。それは(テストする値を取得するために.now()
を使用して)、このように呼ばれることになる
static class IsWeekendQuery implements TemporalQuery<Boolean>{
@Override
public Boolean queryFrom(TemporalAccessor temporal) {
return temporal.get(ChronoField.DAY_OF_WEEK) >= 5;
}
}
:
boolean isItWeekendNow = LocalDateTime.now().query(new IsWeekendQuery());
あるいは、特にUTC時間に(
LocalDateTimeにはタイムゾーン情報がありませんので、ここでGMTと言うのは意味がありません。 – assylias
assyliasがコメントしたように、実際にタイムライン上の実際の瞬間をUTCで操作している場合は、 'インスタント'オブジェクト。 'LocalDateTime'クラスは、タイムライン上のモーメントを表しません。それは可能な瞬間についての曖昧な考えを表している。 –