Java Calendar는 가능한 한 삼가합시다.
tl;dr
Java의 날짜계 처리에 있어서는, Calendar 클래스보다 LocalDate 클래스를 이용합시다.
이상.
이야기
이것은 내 근무처에서 일어난 정말로 있었던 이야기입니다.
사건
2019년 5월 31일 금요일, 소속 프로젝트에서 정기 실행하고 있는 CI가 갑자기 떨어졌다.
Java8로 쓰고 있는 소스 코드의 전체 테스트를 Jenkins를 사용해 하루에 4회 움직이고 있는데, 어제까지 올 그린이었던 것이 갑자기 에러를 토하게 되었다.
에러 로그를 보면, 해당 부분은 Java 표준 라이브러리의 Calendar 클래스의 이용 부분.
사용법으로는 현재 월 당월 일수를 취득하기 위해서다.
테스트 코드에서는, 2017년 6월을 현재 일자로서 모형화하고 있었지만, 테스트 대상 코드는 이하와 같이 되어 있다.
(※ 어디까지나 샘플로, 실제의 코드와는 다릅니다.)
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, LocalDate.now().getYear());
calenar.set(Calendar.MONTH, LocalDate.now().getMonth() - 1); // 月は0から始まるため、例えば1月であれば0をセットする
// 当月の日数を取得
int days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
6월이므로 당연히, 30이 반환값이 되는 것인데, 디버그 해 보면 그것이 31이 되고 있었다.
문제
몇 년 전의 개발 당초부터 계속 움직여 온 테스트 코드가 갑자기 레드가 되어 버렸기 때문에, 라이브러리에 어떠한 수정이 들어갔는지 생각해 여러가지 조사해 보았기 때문에,
해당하는 기사는 특히 보이지 않는다. .
Google 검색에서 'Java calendar b'까지 입력하면 'Java calendar 버그'가 추천 될 정도로 문제가있을 것입니다.
특히 그와 같은 기사는 발견되지 않았지만, 공식적으로 deprecated가 되어 있는 것은 아니지만 그다지 추천되고 있는 것도 아니고,
Java8에서 도입된 LocalDate를 이용합시다는 기사가 발견된 정도.
해결책
LocalDate#lengthOfMonth 을 이용한다.
원래 일단 현재 일자를 취득하는 처리에서 LocalDate를 이용하고 있기 때문에, 그대로 LocalDate 클래스의 메소드를 이용하면 좋은 이야기이지만, 몇 년 전에서는 너무 Java8에서 도입된 LocalData의 이용이 보급되고 있다 없었을 것입니다.
아래와 같이 하면 좋을 뿐.
today = LocalDate.now();
// 当月の日数を取得
int days = today.lengthOfMonth();
이것으로 CI도 무사히 돌게 되었다. 안심하고 업무에 임할 수 있는 번역.
끝.
Reference
이 문제에 관하여(Java Calendar는 가능한 한 삼가합시다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/swallowtail62/items/6bf3a6c7f1fecd50f3d6
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
이것은 내 근무처에서 일어난 정말로 있었던 이야기입니다.
사건
2019년 5월 31일 금요일, 소속 프로젝트에서 정기 실행하고 있는 CI가 갑자기 떨어졌다.
Java8로 쓰고 있는 소스 코드의 전체 테스트를 Jenkins를 사용해 하루에 4회 움직이고 있는데, 어제까지 올 그린이었던 것이 갑자기 에러를 토하게 되었다.
에러 로그를 보면, 해당 부분은 Java 표준 라이브러리의 Calendar 클래스의 이용 부분.
사용법으로는 현재 월 당월 일수를 취득하기 위해서다.
테스트 코드에서는, 2017년 6월을 현재 일자로서 모형화하고 있었지만, 테스트 대상 코드는 이하와 같이 되어 있다.
(※ 어디까지나 샘플로, 실제의 코드와는 다릅니다.)
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, LocalDate.now().getYear());
calenar.set(Calendar.MONTH, LocalDate.now().getMonth() - 1); // 月は0から始まるため、例えば1月であれば0をセットする
// 当月の日数を取得
int days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
6월이므로 당연히, 30이 반환값이 되는 것인데, 디버그 해 보면 그것이 31이 되고 있었다.
문제
몇 년 전의 개발 당초부터 계속 움직여 온 테스트 코드가 갑자기 레드가 되어 버렸기 때문에, 라이브러리에 어떠한 수정이 들어갔는지 생각해 여러가지 조사해 보았기 때문에,
해당하는 기사는 특히 보이지 않는다. .
Google 검색에서 'Java calendar b'까지 입력하면 'Java calendar 버그'가 추천 될 정도로 문제가있을 것입니다.
특히 그와 같은 기사는 발견되지 않았지만, 공식적으로 deprecated가 되어 있는 것은 아니지만 그다지 추천되고 있는 것도 아니고,
Java8에서 도입된 LocalDate를 이용합시다는 기사가 발견된 정도.
해결책
LocalDate#lengthOfMonth 을 이용한다.
원래 일단 현재 일자를 취득하는 처리에서 LocalDate를 이용하고 있기 때문에, 그대로 LocalDate 클래스의 메소드를 이용하면 좋은 이야기이지만, 몇 년 전에서는 너무 Java8에서 도입된 LocalData의 이용이 보급되고 있다 없었을 것입니다.
아래와 같이 하면 좋을 뿐.
today = LocalDate.now();
// 当月の日数を取得
int days = today.lengthOfMonth();
이것으로 CI도 무사히 돌게 되었다. 안심하고 업무에 임할 수 있는 번역.
끝.
Reference
이 문제에 관하여(Java Calendar는 가능한 한 삼가합시다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/swallowtail62/items/6bf3a6c7f1fecd50f3d6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)