무조건 월요일 기준으로 주차 구하기.
현재 진행중인 프로젝트에서 date와 관련된 데이터를 다루는 일이 많다. 웬만하면 Java8 Time API의 기본적인 Methods 로 해결 가능한 경우가 많지만, 계산이 필요한 경우도 더러 있다.
특히 가장 골머리를 썩이게 만든 부분은 몇 주차 계산 이었다. Java8의 Time API에서도 ChronoField의 ALIGNED_WEEK_OF_MONTH를 이용해 손 쉽게 몇 주차인지 알 수 있지만 현재 프로젝트의 요구사항과 맞지 않는 값이었다.
왜 그러한가 찾아보았더니 생각보다 쉽지 않다는걸 깨달았다.
주차를 나누는 국제 표준인 ISO 8601 에서 정하길, 주차를 나누는 기준은 그 주의 시작이 목요일 이후냐 아니냐 (한국 국가기술표준원에선 이를 '어떤 월의 날짜가 그 주간의 과반수 이상을 차지하고 있는가' 로 표현했다.) 로 나뉘는 기준이었고 진행중인 프로젝트에서 원하는 값은 무조건 월요일로 그 주를 시작한다는 것이었다. 예컨대, 2020년 12월 1일은 화요일이지만 월요일이 아니기 때문에 12월 1주차가 아닌 11월 5주차가 되는 것. 이렇게 되면 11월 5주차의 11월은 단 하루지만 요구사항을 맞춰야 하기 때문에 억지로 월요일 기준으로 주차를 나누는 메소드를 작성하였다.
public Integer getWeekNumber (LocalDate date) {
LocalDate firstMondayOfMonth = date.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
// 첫 월요일이면 바로 리턴
if (firstMondayOfMonth.isEqual(date)) return 1;
if (date.isAfter(firstMondayOfMonth)) {
// 첫 월요일 이후일 때
int diffFromFirstMonday = date.getDayOfMonth() - firstMondayOfMonth.getDayOfMonth();
int weekNumber = (int) Math.ceil(diffFromFirstMonday / 7.0);
if (date.getDayOfWeek() == DayOfWeek.MONDAY) weekNumber += 1;
return weekNumber;
}
// 첫 월요일 이전이면 회귀식으로 전 달 마지막 주차를 구함
return getWeekNumber(date.minusMonths(1).with(TemporalAdjusters.lastDayOfMonth()));
}
다행히 이 주차 데이터는 단순 Integer를 return 하거나 String 타입으로 이용해도 상관없어 생각보다 간단하게 작성할 수 있었다.
해당 월의 첫 월요일을 구한 뒤 그 월요일과 해당 날짜의 차를 이용해 구하는 방식을 생각해보았다. 만약 첫 월요일 이전 날짜라면 직전 월의 마지막 날을 회귀식으로 넘겨 구할 수 있게 짰다.
아직 많은 테스트를 거치지 않아 문제점은 나중에 발견될 수 있겠지만 지금은 여기서 만족해야할 것 같다.
'로직과의 사투 > Java' 카테고리의 다른 글
POJO(Plain Old Java Object) 필수 값 Check Annotation 만들기 (0) | 2023.11.10 |
---|---|
자바의 자료구조 Collection Framework (2) - List (0) | 2021.08.09 |
자바의 자료구조 Collection Framework (1) - Map (0) | 2021.06.21 |