배경설명
기준 Date
가 시작 Date
와 종료 Date
사이에 있는지 판단 필요!
- ex)
- 이벤트진행가능여부 (이벤트시작일시~이벤트종료일시)
- 이벤트응모여부 (이벤트응모시작일자~이벤트응모종료일자)
- 날짜 관련 util 함수 추가
- 모든 업무에서
공통적
으로 사용할 수 있는 날짜 관련 기능
일시(yyyyMMddHHmmss)
뿐 아니라 날짜(yyyyMMdd)
등 custom Date format 지원 가능하도록 구현
솔루션
- 날짜 문자열을 숫자로 변환하여 비교 연산자로 비교
- Integer.parseInt(String)
- 이슈 : "yyyyMMddHHmmss" 형식 int 자료형 변환시 할당 공간 범위 초과 (The literal 20230121110000 of type int is out of range)
- Date 클래스의 compareTo() 활용
- 날짜 문자열 -> Date 클래스 변환 필요 -> SimpleDateFormat 활용
소스코드 (DateUtil.java)
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.text.ParseException;
public static boolean isStdDateBetween(String stdDateStr, String startDateStr, String endDateStr, String datefrmt) {
SimpleDateFormat sdf = new SimpleDateFormat(datefrmt, Locale.getDefault());
Date stdDate = new Date();
Date startDate = new Date();
Date endDate = new Date();
int frmtLen = 0;
if (StringUtil.isEmptyTrim(datefrmt)) {
log.info("[isStdDateBetween] datefrmt is empty.");
return false;
} else {
frmtLen = datefrmt.length();
}
if (StringUtil.isEmptyTrim(stdDateStr)
|| StringUtil.isEmptyTrim(startDateStr)
|| StringUtil.isEmptyTrim(endDateStr)
|| StringUtil.isEmptyTrim(datefrmt)
|| stdDateStr.length() != frmtLen
|| startDateStr.length() != frmtLen
|| endDateStr.length() != frmtLen
) {
log.info("[isStdDateBetween] one of params is empty or params length is different.");
return false;
}
try {
stdDate = sdf.parse(stdDateStr);
startDate = sdf.parse(startDateStr);
endDate = sdf.parse(endDateStr);
} catch (ParseException e) {
log.error("[isStdDateBetween] parse error!" + startDateStr + "/" + endDateStr + "/" + datefrmt);
return false;
}
return stdDate.compareTo(startDate) >= 0 && stdDate.compareTo(endDate) <= 0;
}
테스트 (JUnit5)
String stdDateyyyyMMdd = "20230121";
String stdDateyyyyMMddHHmmdd = "20230121110000";
...
@Test
@DisplayName("yyyyMMdd (정상)")
void isDayBetween_true_20230121() {
assertTrue(DateUtil.isStdDateBetween(stdDateyyyyMMdd, "20230121", "20230123", "yyyyMMdd"));
}
@Test
@DisplayName("yyyyMMdd (시작날짜 == 기준날짜)")
void isDayBetween_true_20230121_start_same() {
assertTrue(DateUtil.isStdDateBetween(stdDateyyyyMMdd, "20230121", "20230123", "yyyyMMdd"));
}
@Test
@DisplayName("yyyyMMdd 종료날짜 == 기준날짜)")
void isDayBetween_true_20230121_end_same() {
assertTrue(DateUtil.isStdDateBetween(stdDateyyyyMMdd, "20230119", "20230121", "yyyyMMdd"));
}
@Test
@DisplayName("yyyyMMdd (시작일자 느림)")
void isDayBetween_false_20230121_start_later() {
assertFalse(DateUtil.isStdDateBetween(stdDateyyyyMMdd, "20230129", "20230123", "yyyyMMdd"));
}
@Test
@DisplayName("yyyyMMdd (종료일자 빠름)")
void isDayBetween_false_20230121_end_first() {
assertFalse(DateUtil.isStdDateBetween(stdDateyyyyMMdd, "20230120", "20230119", "yyyyMMdd"));
}
@Test
@DisplayName("yyyyMMdd (공백)")
void isDayBetween_false_empty() {
assertFalse(DateUtil.isStdDateBetween(stdDateyyyyMMdd, "20230120", "", "yyyyMMdd"));
}
@Test
@DisplayName("yyyyMMdd (null)")
void isDayBetween_false_null() {
assertFalse(DateUtil.isStdDateBetween(stdDateyyyyMMdd, null, "20230123", "yyyyMMdd"));
}
@Test
@DisplayName("yyyyMMddHHmmss (정상)")
void isDtmBetween_true_20230121110000() {
assertTrue(DateUtil.isStdDateBetween(stdDateyyyyMMddHHmmdd, "20230121100000", "20230121120000", "yyyyMMddHHmmss"));
}
...
예외
- datefrmt == "yyyyMMdd" && compareDate (startDateStr or endDateStr) 가 당일 case
- 기준날짜 문자열 (stdDateStr) 파라미터 추가
- Date
stdDate
= new Date() 선언 -> Sat Jan 21 12:57:45 KST 2023
- Date
compareDate
= new SimpleDateFormat("yyyyMMdd").parse("20230121") -> Sat Jan 21 00:00:00 KST 2023
- stdDate 가 compareDate 보다 무조건 미래가 되는 현상 발생
- yyyyMMdd case는 시간(HHmmss) 비교 필요 없음!
결론
- 중복 작성될 가능성이 있는 기능은 공통 함수로 모듈화하기 😊
참고