I would like to get all the weeks between 2 dates with weeks that cross 2 months counted twice for each month. For example, in 2021 week 14 of the year hosted both March and April so in this case, I would like that week counted twice (once for March and once for April). I've looked and found just libraries that count the number of weeks between 2 dates. I think I could get week numbers and month numbers and form a unique array but this seems a bit over the top. Has anyone got any suggestions?
CodePudding user response:
weeks that cross 2 months counted twice
The code below allows to do that by utilizing only the standard LocalDate
class and it's methods isBefore()
, plusWeeks()
, plusDays()
.
Keep in mind the days of the week and months are represented by enums from the java.time
package.
I've made a couple of assumptions:
- week starts with Sunday;
- chunks of the week at the start and at the end of the given period have to be taken into account as well as full-length weeks.
public static void main(String[] args) {
System.out.println(getWeekCount(LocalDate.of(2022, 1, 1),
LocalDate.of(2022, 2, 1)));
System.out.println(getWeekCount(LocalDate.of(2022, 1, 1),
LocalDate.of(2022, 3, 1)));
}
public static int getWeekCount(LocalDate date1, LocalDate date2) {
int weekCount = 0;
LocalDate cur = date1;
LocalDate finish = date2;
// assumption: week starts with sunday
// assumption: chunk of week at the start and at the end have to be taken into account as well as full weeks
if (cur.getDayOfWeek() != DayOfWeek.SUNDAY) { // adjusting current date
LocalDate next = cur.plusDays(DayOfWeek.SUNDAY.ordinal() - cur.getDayOfWeek().ordinal() 1);
weekCount = getWeeksIncrement(cur, next);
cur = next;
}
if (finish.getDayOfWeek() != DayOfWeek.SUNDAY) { // adjusting finish date
LocalDate previous = finish.minusDays(finish.getDayOfWeek().ordinal() 1);
weekCount = getWeeksIncrement(previous, finish);
finish = previous;
}
while (cur.isBefore(finish) || cur.equals(finish)) {
LocalDate next = cur.plusWeeks(1);
weekCount = getWeeksIncrement(cur, next);
cur = next;
}
return weekCount;
}
public static int getWeeksIncrement(LocalDate cur, LocalDate next) {
return weekIsSharedBetweenTwoMonth(cur, next) ? 2 : 1;
}
public static boolean weekIsSharedBetweenTwoMonth(LocalDate cur, LocalDate next) {
return next.getMonth() != cur.getMonth() &&
next.withDayOfMonth(1).isAfter(cur);
}
Output
7 - weeks between: 2022-01-01 and 2022-02-01
12 - weeks between: 2022-01-01 and 2022-03-01
CodePudding user response:
You can get the weeknumber like this using java.time:
LocalDate date = LocalDate.of(year, month, day);
int weekOfYear = date.get(ChronoField.ALIGNED_WEEK_OF_YEAR);
You did not mention which java version you are using. java.time was introduced in java 8. There are other solutions available for pre-java 8.
Based on the above, you should be able to solve your problem.