Developing a timesheet selection page where the selection should be pre-populated with list of end of week dates for last three months. Need an process with O(n) using Java 8 time API.

My current solution checks for if current date is Sunday, if not find out the end of this week and then iterate back for three months. Looking for an optimized solution.

3

There are 3 answers

1
JodaStephen On BEST ANSWER

In JDK 9 there is a new method, datesUntil.

// today, but make sure you consider time-zones when using this method
LocalDate today = LocalDate.now();

// find the next Sunday
LocalDate endSun = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));

// find 3 months earlier (there are 13 weeks in 3 months)
LocalDate startSun = endSun.minusWeeks(13);

// find dates
Stream<LocalDate> dates = startSun.datesUntil(endSun, Period.ofWeeks(1));
0
Flown On

I've answered a similar question HERE.

We've to check how many weeks are in between the last Saturday and the date three months ago. Then it's simple math:

LocalDate lastSunday = LocalDate.now()
  .with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY));

long weeks = ChronoUnit.WEEKS.between(lastSunday.minusMonths(3L), lastSunday);

List<LocalDate> collect = Stream.iterate(lastSunday.minusWeeks(weeks), d -> d.plusWeeks(1L))
  .limit(weeks + 1)
  .collect(Collectors.toList());
0
Jacob G. On

A Java 8 answer would be the following (if you're only looking for Sundays):

LocalDate closestSunday = LocalDate.now().with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY));
LocalDate firstSunday = closestSunday.minusMonths(3);

List<LocalDate> sundays = new ArrayList<>();

for (; !closestSunday.isBefore(firstSunday); closestSunday = closestSunday.minusWeeks(1)) {
    sundays.add(closestSunday);
}

I would use a Stream approach, but I'd rather wait 8 days until JDK 9 is released so I can use Stream#takeWhile.

EDIT: If you really want a Stream approach utilizing JDK 8, then the following is logically equivalent to the code above:

LocalDate closestSunday = LocalDate.now().with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY));
LocalDate secondSunday = closestSunday.minusMonths(3).plusWeeks(1);

List<LocalDate> sundays = new ArrayList<>();

Stream.iterate(closestSunday, date -> date.minusWeeks(1))
      .peek(sundays::add)
      .allMatch(date -> date.isAfter(secondSunday));