The following class should do this:
public class NrfMonthWeek {
public static NrfMonthWeek getWeek(LocalDate date) {
LocalDate firstDayOfNrfYear = date.with(MonthDay.of(Month.JANUARY, 29))
.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
if (date.isBefore(firstDayOfNrfYear)) {
firstDayOfNrfYear = date.minusYears(1)
.with(MonthDay.of(Month.JANUARY, 29))
.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
}
int weekOfNrfYear = (int) ChronoUnit.WEEKS.between(firstDayOfNrfYear, date) + 1;
assert 1 <= weekOfNrfYear && weekOfNrfYear <= 53 : weekOfNrfYear;
YearMonth firstMonthOfNrfYear = YearMonth.from(firstDayOfNrfYear)
.with(Month.FEBRUARY);
if (weekOfNrfYear == 53) {
return new NrfMonthWeek(firstMonthOfNrfYear.plusMonths(11), 5);
} else {
int monthOfNrfYear = (weekOfNrfYear * 3 + 11) / 13;
int weeksBeforeMonth = (monthOfNrfYear * 13 - 12) / 3;
int weekOfMonth = weekOfNrfYear - weeksBeforeMonth;
return new NrfMonthWeek(
firstMonthOfNrfYear.plusMonths(monthOfNrfYear - 1), weekOfMonth);
}
}
private YearMonth month;
private int weekOfMonth;
public NrfMonthWeek(YearMonth month, int weekOfMonth) {
this.month = Objects.requireNonNull(month);
if (weekOfMonth < 1 || weekOfMonth > 5) {
throw new IllegalArgumentException("Incorrect week number " + weekOfMonth);
}
this.weekOfMonth = weekOfMonth;
}
@Override
public String toString() {
return month.getMonth().getDisplayName(TextStyle.FULL, Locale.US)
+ " Week " + weekOfMonth;
}
}
. getWeek:
System.out.println(NrfMonthWeek.getWeek(LocalDate.of(2018, Month.MARCH, 4)));
System.out.println(NrfMonthWeek.getWeek(LocalDate.of(2018, Month.APRIL, 1)));
:
March Week 1
March Week 5
, , getWeek.
. , , , , . , . , java.time, Java- , .
, NrfMonthWeek, 5- , 5 . . unit test.
, , : , , NRF 4-5-4 . , - , 4 . , , 4 . , , 29 4 . , , 5 . 53- 5 .