Find the first day of the last week of the year with java.time

I need to find the first day of the last week of the year using the Java 8 Date and Time API ( java.time ) and finally come to this solution:

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);

This decision will find the first week of the next year, if necessary, change the day of the week to Monday and move to 7 days ago. Is there a smarter way to achieve the same result?

+4
source share
4 answers

As suggested, I will answer the question myself (with a little amplification from the comments), since there does not seem to be a much simpler solution.

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);
+3
source

UPDATED based on your comment:

, . WeekBasedYear , weekBasedYear , :

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);

:

2012-12-24

, .

+4

, , OP, - , ISO- , . , LocalDate.of(date.getYear() + 1, 1, 7) (. lastWeekOfYearOld(...)). , ( -), lastWeekOfYearCorrect(...). , - (. 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

TL;DR

org.threeten.extra.YearWeek.from(  // Represents an entire week at a time, using standard ISO 8601 definition of "week". 
    LocalDate.of( 2016 , Month.FEBRUARY , 17 )
)                                  // Returns a `YearWeek` object to represent the week containing that date. 
.plusYears( 1 )                    // Move to following year.
.withWeek( 1 )                     // Move to the first week of that following year.
.minusWeeks( 1 )                   // Move to the prior week, which would be the last week of our desired week-based-year.
.atDay(                            // Determine the date of a particular day-of-week within that week.
    DayOfWeek.MONDAY               // Use the handy `java.time.DayOfWeek` enum predefining seven objects, one for each day of the week.
)                                  // Returns a `LocalDate` object.
.toString()                        // Generate a String representing this `LocalDate` value in standard ISO 8601 format.

2016-12-26

YearWeek

ThreeTen-Extra , , java.time.

YearWeek . , ISO 8601.

-.

YearWeek yw = YearWeek.now( ZoneId.of( "Africa/Tunis" ) ) ;  // Get the current year-week as seen in the wall-clock time of people inhabiting a particular region (a time zone). 

YearWeek .

LocalDate ld = LocalDate.of( 2016 , Month.FEBRUARY , 17 ) ;  // Feb 2, 2016.
YearWeek yw = YearWeek.from( ld ) ;

: 52 53. if-else.

int w = yw.is53WeekYearโ€‹() ? 53 : 52 ;  // Determine last week number, either 52 or 53.

.

YearWeek ywLastOfYear = yw.withWeek( w ) ; // Produce a new `YearWeek` object based on the originalโ€™s values but for some adjustment - here we use the same year but use a different week number.

, , - .

LocalDate firstDayOfLastYearWeek = ywLastOfYear.atDay( DayOfWeek.MONDAY ) ; 

. . tl; dr .

0

All Articles