2017-06-02 7 views
3

前回の日曜日、前の日曜日、または前の日曜日をどのように計算するのですか。一般にn週前の日曜日を見つける方法を教えてください。今日は日曜日であれば、それは先週の日曜日ではなく、今日に戻るべきです。Java date time APIまたはJoda-timeでn番目の前週の日曜日を見つける方法は?

Joda-TimeまたはJava 8時間ソリューションを探しています。

編集: 私は

DateTime sunday = now 
    .minusWeeks(1) 
    .withDayOfWeek(DateTimeConstants.SUNDAY) 
    .wi‌​thTimeAtStartOfDay()‌​; 
DateTime previousWeekSunday = now 
    .minusWeeks(2) 
    .withDayOfWeek(DateTimeConstants.SATURDAY) 
    .‌​withTime(23, 59, 59, 999); 

を試みたが、現在は日曜日であれば、それは今日の日付を与えないよう、このロジックは失敗します。

+3

https://docs.oracle.com/javase/tutorial/datetime/でチュートリアルを読んでから、試してみることをお勧めします。 –

+1

Joda-TimeよりもJava 8を好むべきだと思われます。 [The Joda-Time homepage](http://www.joda.org/joda-time/)では、「ユーザーは現在、java.time(JSR-310)に移行するように求められています。」 –

+0

検索とリサーチ持ってくる?あなたは何を試しましたか(どのように失敗しましたか)? –

答えて

4

は、基本的には今日は日曜日であれば、その後...前のもののために戻って見ていない場合は、チェックする必要があります(または再帰的にあなたがそれに前のものが必要な場合は、日付を戻す...)

Javaの8を使用して次のものが必要です。


LocalDate date = LocalDate.now(); 
DayOfWeek todayAsDayOfWeek = date.getDayOfWeek(); 
LocalDate prevSun = todayAsDayOfWeek == DayOfWeek.SUNDAY ? date : date.with(TemporalAdjusters.previous(DayOfWeek.SUNDAY)); 
System.out.println(prevSun); 

編集:previousOrSame方法は質問は、すでにJavaの8アプローチと答えたが、ちょうどレコードの週た

LocalDate date = LocalDate.now(); 
    LocalDate prevSun = date.with(TemporalAdjusters.previous(DayOfWeek.SUNDAY)); 

    prevSun = date.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY)); 
    System.out.println(prevSun); 
+3

'TemporalAdjuster'の' previousOrSame'は同じことを1ステップで行います。 – Magnus

+1

先週の日曜日(または今日の日曜日)を見つけたら、 'prevSun.minusWeeks(n)'を使って日曜日を逆算することができます。 –

+1

それにもかかわらず、違いを生むかもしれない詳細:タイムゾーンを明示的にするために、 'LocalDate.now()'に引数を渡すことを好みます。 'ZoneId.systemDefault()'を渡す場合でも。このようにして、あなたはタイムゾーンを考え、あなたが望むものを決めたことを読者 - あなた自身 - に伝えています。 –

1

実際DAYOFのチェックをスキップしますここにはJoda-Timeのソリューション(Java 8の2セントもあります)があります。

私が正しく理解している場合、前の日曜日 n番目を取得するための一般的なアルゴリズムである、:

  • 現在の日付がすでに日曜日であればn=1のために、それを返すので、(n-1週間戻って同じ日付)他
  • 、私が受け取るメソッドを作成したその日

から番目の前の日曜日のnを見つけますn(週数)およびDateTime(開始日)。コードは

// get the n'th previous Sunday, from the given DateTime 
public DateTime nPreviousSunday(int n, DateTime dateTime) { 
    // avoid zero or negative numbers (optional, see if it fits your use cases) 
    if (n <= 0) { 
     return dateTime; // return the same date 
    } 

    DateTime d = dateTime; 

    // get first previous (or same) Sunday 
    int dow = d.getDayOfWeek(); 
    if (dow != DateTimeConstants.SUNDAY) { // not a Sunday, adjust the day to the previous one 
     int diff = DateTimeConstants.SUNDAY - dow; 
     // DateTimeConstants.SUNDAY is 7, so diff is always positive 
     // d is (7 - diff) days ahead of Sunday, adjusting 
     d = d.minusDays(7 - diff); 
    } 

    // find the n'th previous (considering that the first was already found above) 
    d = d.minusWeeks(n - 1); 

    return d; 
} 

です。以下は04/06/2017(日曜日)のテストです。n=1のために、それは04/06/2017を返し、n >= 2のためには、(04/06/2017自体は最初のものであることを考慮して)その日から、前の日曜日 n番目を見つける:

System.out.println(nPreviousSunday(1, new DateTime(2017, 6, 4, 10, 0))); // 2017-06-04 
System.out.println(nPreviousSunday(2, new DateTime(2017, 6, 4, 10, 0))); // 2017-05-28 
System.out.println(nPreviousSunday(3, new DateTime(2017, 6, 4, 10, 0))); // 2017-05-21 

05/06/2017のテスト(ない日曜日)、それ(最初の前の日曜日は04/06/2017あると)同じ結果を得る:土曜日までに一週間のための

System.out.println(nPreviousSunday(1, new DateTime(2017, 6, 5, 10, 0))); // 2017-06-04 
System.out.println(nPreviousSunday(2, new DateTime(2017, 6, 5, 10, 0))); // 2017-05-28 
System.out.println(nPreviousSunday(3, new DateTime(2017, 6, 5, 10, 0))); // 2017-05-21 

テスト(10/06/2017):

System.out.println(nPreviousSunday(1, new DateTime(2017, 6, 6, 10, 0))); // 2017-06-04 
System.out.println(nPreviousSunday(1, new DateTime(2017, 6, 7, 10, 0))); // 2017-06-04 
System.out.println(nPreviousSunday(1, new DateTime(2017, 6, 8, 10, 0))); // 2017-06-04 
System.out.println(nPreviousSunday(1, new DateTime(2017, 6, 9, 10, 0))); // 2017-06-04 
System.out.println(nPreviousSunday(1, new DateTime(2017, 6, 10, 10, 0))); // 2017-06-04 

System.out.println(nPreviousSunday(3, new DateTime(2017, 6, 6, 10, 0))); // 2017-05-21 
System.out.println(nPreviousSunday(3, new DateTime(2017, 6, 7, 10, 0))); // 2017-05-21 
System.out.println(nPreviousSunday(3, new DateTime(2017, 6, 8, 10, 0))); // 2017-05-21 
System.out.println(nPreviousSunday(3, new DateTime(2017, 6, 9, 10, 0))); // 2017-05-21 
System.out.println(nPreviousSunday(3, new DateTime(2017, 6, 10, 10, 0))); // 2017-05-21 

PS:私はDateTimeを使用していますが、あなたはまた(ちょうどメソッドで変数の型を変更するアルゴリズムは同じである)org.joda.time.LocalDateまたはorg.joda.time.LocalDateTimeのためにこのコードを使用することができます。


のJava 8のアプローチ(私の2セント)

のJava 8では、あなたはalready answeredとしてTemporalAdjusterを使用することができます。しかし、ちょうど私の2セントを入れて、あなたはTemporalAdjusterを返すメソッドを作成することができ、その後、あなたは、java-time型のいずれかでそれを使用することができます。

:だから、あなたはこのようにそれを使用することができ

// get the n'th previous dayOfWeek, from the given temporal 
public TemporalAdjuster previous(int n, DayOfWeek dayOfWeek) { 
    return (temporal) -> { 
     // avoid zero or negative numbers (optional, see if it fits your use cases) 
     if (n <= 0) { 
      return temporal; // return the same temporal 
     } 

     // get first previous (or same) dayOfWeek 
     Temporal t = temporal.with(TemporalAdjusters.previousOrSame(dayOfWeek)); 

     // find the n'th previous (considering that the first was already found above) 
     t = t.minus(n - 1, ChronoUnit.WEEKS); 

     return t; 
    }; 
} 

System.out.println(LocalDate.of(2017, 6, 4).with(previous(1, DayOfWeek.SUNDAY))); // 2017-06-04 
System.out.println(LocalDate.of(2017, 6, 4).with(previous(2, DayOfWeek.SUNDAY))); // 2017-05-28 
System.out.println(LocalDate.of(2017, 6, 4).with(previous(3, DayOfWeek.SUNDAY))); // 2017-05-21 

System.out.println(LocalDate.of(2017, 6, 5).with(previous(1, DayOfWeek.SUNDAY))); // 2017-06-04 
System.out.println(LocalDate.of(2017, 6, 5).with(previous(2, DayOfWeek.SUNDAY))); // 2017-05-28 
System.out.println(LocalDate.of(2017, 6, 5).with(previous(3, DayOfWeek.SUNDAY))); // 2017-05-21 

良いことは、それはまた別の種類で動作するということです。

LocalDateTime dt = LocalDateTime.of(2017, 6, 4, 10, 0); 
System.out.println(dt.with(previous(1, DayOfWeek.SUNDAY))); // 2017-06-04T10:00 
System.out.println(dt.with(previous(2, DayOfWeek.SUNDAY))); // 2017-05-28T10:00 

ZonedDateTime zdt = ZonedDateTime.of(dt, ZoneId.of("America/Sao_Paulo")); 
System.out.println(zdt.with(previous(1, DayOfWeek.SUNDAY))); // 2017-06-04T10:00-03:00[America/Sao_Paulo] 
System.out.println(zdt.with(previous(2, DayOfWeek.SUNDAY))); // 2017-05-28T10:00-03:00[America/Sao_Paulo] 

OffsetDateTime odt = OffsetDateTime.of(dt, ZoneOffset.ofHours(2)); 
System.out.println(odt.with(previous(1, DayOfWeek.SUNDAY))); // 2017-06-04T10:00+02:00 
System.out.println(odt.with(previous(2, DayOfWeek.SUNDAY))); // 2017-05-28T10:00+02:00 

previous()方法はTemporalAdjusterを返すと、あなたは毎回それを呼び出す必要はありません、チュSTストア変数で調整して再利用:

TemporalAdjuster thirdPreviousSunday = previous(3, DayOfWeek.SUNDAY); 
System.out.println(LocalDate.of(2017, 6, 4).with(thirdPreviousSunday)); // 2017-05-21 
System.out.println(LocalDate.of(2017, 6, 5).with(thirdPreviousSunday)); // 2017-05-21 

このアプローチのもう一つの利点は、以下のとおりです。コードは(IMO)は、より読みやすく、きれいになり、それが週の任意の日で動作します。


PS:タイプ(のみ時/分/秒/ナノ秒を有しLocalTime等)DayOfWeekフィールドを持っていない場合以下のコードは例外をスロー:

// throws UnsupportedTemporalTypeException (because LocalTime doesn't have the DayOfWeek field) 
LocalTime.now().with(previous(1, DayOfWeek.SUNDAY)); 
として、

// also throws exception (Unsupported field: DayOfWeek) 
LocalTime.now().with(TemporalAdjusters.previous(DayOfWeek.SUNDAY)); 

それは理にかなって:

はちょうどそれは、既存の調整で発生することを思い出させますには日付フィールドがなく、平日については知ることができません。

関連する問題