2016-05-12 8 views
4

Ich brauche den ersten Tag der letzten Woche eines Jahres mit Java 8 Datum und Uhrzeit API (java.time) und schließlich kam zu dieser Lösung zu finden:Suche letzte Woche des Jahres mit java.time

LocalDate date = LocalDate.of(2016, 2, 17); 
LocalDate lastWeekOfYear = LocalDate.of(date.getYear() + 1, 1, 7) 
    .with(WeekFields.ISO.weekOfYear(), 1) 
    .with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).minusDays(7); 

Diese Lösung findet die erste Woche des nächsten Jahres, passt den Wochentag ggf. an Montag an und zieht 7 Tage zurück. Gibt es einen klügeren Weg, um das gleiche Ergebnis zu erzielen?

+2

ich sieht okay, obwohl ich wahrscheinlich verwenden würde 'minusWeeks (1) 'statt' minusDays (7) ', und setze es in eine neue Zeile.Sie könnten möglicherweise Ihren' TemporalAdjuster' für 'lastWeekOfWeekYear' schreiben –

+3

Eine Alternative (nicht unbedingt besser lesbar) wäre' date.with (lastDayOfYear()) .minusDays (7 - WeekFields.ISO.getMinimalDaysInFirstWeek()). mit (previousOrSame (MONDAY)) ' – assylias

+0

@Oxolotl Ich schlage vor, dass Sie Ihre vorgeschlagene Lösung extrahieren und als Antwort posten. Sie können es später akzeptieren, um die Frage zu kennzeichnen als geschlossen.Komplett in Ordnung, um Ihre eigene Frage auf Stack Overflow zu beantworten.Oder –

Antwort

3

Wie vorgeschlagen, werde ich die Frage selbst beantworten (mit einer kleinen Verbesserung aus den Kommentaren), da es keine wesentlich einfachere Lösung zu sein scheint.

LocalDate date = LocalDate.of(2016, 2, 17); 
LocalDate lastWeekOfYear = LocalDate.of(date.getYear() + 1, 1, 7) 
    .with(WeekFields.ISO.weekOfWeekBasedYear(), 1) 
    .with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).minusWeeks(1); 
4

auf Ihrem Kommentar UPDATED basiert:

Sie ab Ihrem beginnen können, den letzten Tag des Jahres erhalten und bis Montag zurück. Holen Sie sich das WeekBasedYear dieses Ergebnisses und akzeptiert es, wenn der weekBasedYear die gleichen wie am ersten Tag Jahr, otherways zum vorherigen Montag zurück und akzeptiert es als Ergebnis:

LocalDate day = LocalDate.of(2012, 2, 17); 
LocalDate result = day.with(TemporalAdjusters.lastDayOfYear()) 
          .with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));  

//if day and result weekBasedYear are in the same weekYear then result else go back to previous Mondays 
result = result.get(WeekFields.ISO.weekBasedYear())== day.getYear()? result : 
       result.with(TemporalAdjusters.previous(DayOfWeek.MONDAY)); 

System.out.println(result); 

Ausgang:

2012-12-24 

Hoffnung Das kann helfen.

+0

Ich denke, diese Lösung liefert falsche Ergebnisse für den Fall, dass der letzte Tag des Jahres ein Montag, Dienstag oder Mittwoch ist. Zum Beispiel beginnt 2012 die letzte Woche des Jahres am 2012-12-24, während der obige Code 2012-12-31 zurückgibt. Ich hätte in meiner Frage darauf hinweisen sollen, dass ich die letzte Woche nach ISO 8601 Woche benötige (siehe [https://en.wikipedia.org/wiki/ISO_8601#Week_dates]). – Oxolotl

+0

@Oxolotl Ja, Sie sollten sicherlich Ihre Bedingungen definiert haben, in diesem Fall, was Sie mit Woche des Jahres meinen.Bitte bearbeiten Sie Ihre Frage mit solchen Klarstellungen und nicht als Kommentare. –

0

ich die letzte Lösung denken von OP gefunden ist immer noch nicht richtig, weil wir im Rahmen der ISO-Wochen-Termine verschieben, keine gewöhnlichen Kalenderdaten. Daher ist der Ausdruck LocalDate.of(date.getYear() + 1, 1, 7) oft um die Jahresgrenze falsch (siehe die Beispielmethode lastWeekOfYearOld(...)). Stattdessen müssen wir ein Kalenderjahr hinzufügen, nicht ein Kalenderjahr (gebunden an Januar-Dezember), das jetzt in der zweiten Methode lastWeekOfYearCorrect(...) verwendet wurde. Ich zeigt auch eine andere korrekte Alternative basierend auf dem kontextsensitiven Wertebereich des Woche-of-Jahres-Bereichs (siehe Methode lastWeekOfYearAlternative(...).

public static void main(String[] args) { 
    System.out.println(
       lastWeekOfYearOld(LocalDate.of(2015, 12, 31))); // 2015-12-28 (OK) 
    System.out.println(
       lastWeekOfYearOld(LocalDate.of(2016, 1, 1))); // 2016-12-26 (Wrong) 

    System.out.println(
       lastWeekOfYearCorrect(LocalDate.of(2015, 12, 31))); // 2015-12-28 (OK) 
    System.out.println(
       lastWeekOfYearCorrect(LocalDate.of(2016, 1, 1))); // 2015-12-28 (OK) 

    System.out.println(
       lastWeekOfYearAlternative(LocalDate.of(2015, 12, 31))); // 2015-12-28 (OK) 
    System.out.println(
       lastWeekOfYearAlternative(LocalDate.of(2016, 1, 1))); // 2015-12-28 (OK) 
} 

private static LocalDate lastWeekOfYearOld(LocalDate date) { 
    return LocalDate.of(date.getYear() + 1, 1, 7) 
     .with(WeekFields.ISO.weekOfWeekBasedYear(), 1) 
     .with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).minusWeeks(1); 
} 

private static LocalDate lastWeekOfYearCorrect(LocalDate date) { 
    date = 
     date.plus(1, IsoFields.WEEK_BASED_YEARS) 
      .with(DayOfWeek.MONDAY) 
      .with(WeekFields.ISO.weekOfWeekBasedYear(), 1); 
    return date.minusWeeks(1); 
} 

private static LocalDate lastWeekOfYearAlternative(LocalDate date) { 
    TemporalField woyField = WeekFields.ISO.weekOfWeekBasedYear(); 
    date = date.with(woyField, woyField.rangeRefinedBy(date).getMaximum()); 
    return date.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); 
} 
+0

Die obige Lösung funktioniert nicht wie erwartet für mich, aber ich verstehe Ihren Standpunkt und denke, dass meine Frage möglicherweise noch unklar ist. Ich suchte nach einer Lösung für die Frage "Was ist die letzte Woche von 2016?" - Die Tages- und Monatskomponenten des übergebenen 'LocalDate' sind daher irrelevant. Es wäre klarer, wenn ich nach einer Implementierung einer Methode mit der Signatur LocalDate lastWeekOfYear (int year) gefragt hätte. – Oxolotl

Verwandte Themen