달력에 필요한 직전 달 일정, 다음 달 일정 가져오려고 한다. 2023년 5월을 예시로 들면, 직전 달 날짜인 4월 30일과 다음 달 날짜인 6월 1, 2, 3일의 일정이 필요하다. 직전 달 날짜를 구하는 기능을 먼저 설명하겠다.
LocalDate.of
함수를 이용해서 해당 달 1일을 LocalDate 형식 객체를 만든다.LocalDate date = LocalDate.of(year, month, 1);
DayOfWeek dayOfWeek = date.getDayOfWeek();
return dayOfWeek.getValue(); // 월요일은 1, 일요일은 7
getValue() 함수 말고 dayOfWeek.getDisplayName()를 이용하면 문자열로 반환받을 수 있다.
월요일은 1, 일요일은 7을 반환하므로 그대로 이용하면 된다. 다만, 일요일인 경우 필요한 요일이 없으므로 0을 반환하게 한다.
public int getRemainingDay(int numberOfDay) {
if(numberOfDay == 7) {
return 0;
} else {
return numberOfDay;
}
}
SQL에서 사용할 Date 객체를 만들기 위해 yearMonth → LocalDate → Date로 형변환했다.
YearMonth yearMonth = YearMonth.of(year, month);
LocalDate firstDayOfMonth = yearMonth.atDay(1);
Date firstDateOfMonth = Date.valueOf(firstDayOfMonth); // 해당 월의 첫번째 날짜
DATE_SUB를 이용하기 위해 nativeQuery 사용한다.
between을 이용해 날짜 사이의 일정을 구한다.
@Query(nativeQuery = true, value = "select * from task where writer = :memberId " +
"and is_active = true " +
"and start_at between DATE_SUB(:firstDateOfMonth, INTERVAL :remainingDay DAY) and :firstDateOfMonth " +
"order by start_at asc")
List<Task> findTaskOfBeforeMonth(String memberId, Date firstDateOfMonth, int remainingDay);
달마다 마지막 날짜가 다르므로 주의하자.
public int getLastDayOfMonth(int year, int month) {
YearMonth yearMonth = YearMonth.of(year, month);
return yearMonth.lengthOfMonth(); // 해당 월의 마지막 날짜
}
나머지 과정은 직전 달 일정과 같다.
DATE_ADD를 이용하기 위해 nativeQuery 사용한다.
between을 이용해 날짜 사이의 일정을 구한다.
@Query(nativeQuery = true, value = "select * from task where writer = :memberId " +
"and is_active = true " +
"and start_at between :lastDayOfMonth and DATE_ADD(:lastDayOfMonth, INTERVAL :remainingDay DAY) " +
"order by start_at asc")
List<Task> findTaskOfAfterMonth(String memberId, Date lastDayOfMonth, int remainingDay);