티스토리 뷰
Date, Calendar 클래스의 문제점
예전에 본 글이지만 정리할 생각은 따로 없었는데, 사내 개발 자료 공유 차원에서 wiki에 정리하다보니 블로그 생각도 나서 간만에 글을 쓰게 되었다.
(위 글의 요약에 불과하며 직접 들어가서 보는걸 추천합니다!)
1) 불변 객체가 아니다
set 메서드가 있어서 악의적으로 값 변경시 기존 사용하는 date 값의 side effect가 있을 수 있다.
2) int 상수 필드 남용
calendar.add(Calendar.SECOND, 2);
첫번째 파라미터에 Calendar.JUNE 등 엉뚱한 상수가 들어가도 컴파일 시점에서 확인이 어렵다.
3) 헷갈리는 월 지정
calendar.set(2021, 5, 3);
1월 = 0으로 표현되어 예제의 값은 Calendar.JUNE과 같다.
4) 일관성 없는 요일 상수
어떤 메서드에서는 일요일 = 0, 어떤 메서드에서는 일요일 = 1
5) Date와 Calendar의 역할 분담
날짜 계산은 Date 클래스만으로 부족해 Calendar 객체를 생성해야하는데 생성 비용도 비싸고 번거롭다.
6) java.util.Date 하위 클래스 문제
LocalDate의 사용
LocalDate로 년월일 구하고 파싱하고 등등은 다른 분들이 깔끔하게 정리해주신게 많다!
그래서 나는 주로 사용하였던 localdate 예시 몇가지만 올리고 마무리해야겠다.
@Test
public void 현재날짜_스트링포멧_적용() throws Exception {
String nowYearMonth = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMM")); // yyyyMMdd로 포멧 변환시 일자까지 변환 가능
assertThat(nowYearMonth, is("202105")); // Test Pass (테스트 현재 날짜 : 20210503)
}
@Test
public void 스트링날짜_localdate형식으로_파싱() throws Exception {
String dateStr = "20210503";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate parsedDate = LocalDate.parse(dateStr, formatter);
assertThat(parsedDate, is(LocalDate.now())); // Test Pass (테스트 현재 날짜 : 20210503)
}
@Test
public void 만나이_계산() throws Exception {
String birthDate = "19891111";
String standardYm = "202105";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate parsedBirthDate = LocalDate.parse(birthDate, formatter);
LocalDate parsedStandardYm = LocalDate.parse(standardYm + "01", formatter);
// parsedStandardYm.with(TemporalAdjusters.lastDayOfMonth() : 기준월의 마지막날짜 기준으로 하기 위함 (기대값 : 20210531)
int age = parsedBirthDate.until(parsedStandardYm.with(TemporalAdjusters.lastDayOfMonth())).getYears();
assertThat(age, is(31)); // Test Pass
}
@Test
public void 기간_계산() throws Exception {
String targetDt = "20210503"; // 목표일자
String standardDt = "20200503"; // 기준일자
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate targetLocalDt = LocalDate.parse(targetDt, formatter);
LocalDate standardLocalDt = LocalDate.parse(standardDt, formatter);
//ChronoUnit.DAYS.between(일수 차이), ChronoUnit.YEARS.between(년수 차이) 필요에 따라 변경 가능
int workPeriod = (int) ChronoUnit.MONTHS.between(standardLocalDt, targetLocalDt);
assertThat(workPeriod, is(12)); // Test Pass
}
@Test
public void 날짜_영문_표시() throws Exception {
String engMonthShortName = LocalDate.of(2021, 01, 01).getMonth().getDisplayName(TextStyle.SHORT, Locale.US);
String engDayShortName = LocalDate.of(2021, 01, 01).getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.US);
String engMonthFullName = LocalDate.of(2021, 01, 01).getMonth().getDisplayName(TextStyle.FULL, Locale.US);
String engDayFullName = LocalDate.of(2021, 01, 01).getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.US);
assertThat(engMonthShortName, is("Jan")); // Test Pass
assertThat(engDayShortName, is("Fri")); // Test Pass
assertThat(engMonthFullName, is("January")); // Test Pass
assertThat(engDayFullName, is("Friday")); // Test Pass
}
'JAVA' 카테고리의 다른 글
문자열 연결 (String Concatenation) (0) | 2021.05.13 |
---|---|
List.sort(Comparator) - 숫자 정렬 (1, 2...) / 문자 + 숫자 정렬 (A01, A02...) (0) | 2020.11.29 |
HttpURLConnection GET/POST 전송 및 Test 방법 (4) | 2019.10.30 |
이진탐색(Binary Search)을 활용해 효율적으로 서치하기 (0) | 2018.12.10 |
이중for문, 중첩for문, 중첩된 반복문 활용하기 (0) | 2018.11.21 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 문자열 내 마음대로 정렬하기
- Spring
- 객체지향과 디자인패턴
- 쇠막대기
- java
- 다음 맵 api
- FrogJmp
- 자바
- codility
- 텔레그램
- 노션트렐로광고X
- 스프링 부트
- 기능개발
- json
- 안드로이드 스튜디오
- 카카오인턴
- AWS
- K번째수
- 알고리즘
- API
- 완주하지 못한 선수
- 타겟 넘버
- cgv
- 맵 api
- 파이팅코리아
- 프로그래머스
- 예매 알림
- 최솟값
- 더 나은 내일
- 124 나라의 숫자
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함