왜 Calendar class의 MONTH만 0부터 시작할까?
실용적 관점에서 보면 지금은 Calendar class를 쓰지 않고 Java8부터 새로 추가된 java.time package를 쓰는 게 더 명확하고 실수할 일도 없어 더 생산적이다. Oracle사에서도 공식 가이드라인 문서인 JSR-310에서 java.util.Calendar를 비롯한 몇 가지 내장 Class는 문제가 있어 java.time package를 사용하라고 권고하고 있다. 당장 Calendar를 사용한 code를 개선하는 게 시급한 사람이라면 아래 문서를 참조하기 바란다.
https://belief-driven-design.com/essentials-of-java-time-59cff478fdf/
Essentials of Java’s Time API (JSR-310) | belief driven design
Dealing with date and time is a cumbersome task in many programming languages. But with Java 8, the JDK provides us with a comprehensive and completely new API, changing the way we deal with time-related concepts. Even though JSR310 was introduced with Jav
belief-driven-design.com
그런데 나는 애초에 왜 MONTH만 0부터 시작하게 만들어서 사람들을 헷갈리게 만든지가 궁금했다.
Calendar class의 유래는 C 언어의 표준 시간 구조체(structure)인 struct tm까지 올라간다. Java desingner가 Calendar 문법을 설계할 때 C 언어의 struct tm을 참조했다는 것이다. struct tm도 누군가 만든 것일 거고 그럼 왜 그렇게 만든 지를 알아봐야 할 것 아닌가?
struct tm은 다음과 같은 구조다.
struct tm {
int tm_sec; // 초 (0-59)
int tm_min; // 분 (0-59)
int tm_hour; // 시 (0-23)
int tm_mday; // 일 (1-31)
int tm_mon; // 월 (0-11, 0 = 1월)
int tm_year; // 년 (1900년부터의 연도)
int tm_wday; // 요일 (0-6, 0 = 일요일)
int tm_yday; // 연중 일자 (0-365, 1월 1일 = 0)
int tm_isdst; // 일광 절약 시간 플래그
};
code를 보면 어? C언어에선 아예 '일' 빼고 다 0으로 시작하네라는 생각이 들거다. 여기서부턴 stackoverflow의 senior 개발자들조차 100% 확신하지 못하는 내용인데 가장 유력한 추측은 이렇다.
C언어가 만들어질 당시엔 memory 용량이 매우 작았기 때문에 1부터 시작함으로써 생기는 dummy data 0조차 용납할 수 없었다고 한다. 그래서 programming 효율을 위해 반드시 1부터 시작해야 하는 '일'을 제외한 나머지는 0부터 시작하게 설계했다고 한다. 1985년 출시된 슈퍼마리오 브라더스가 40KB인데 C언어는 이보다 더 전인 1972년에 제작되었으니 그럴만하다.
Java가 만들어질 때는 memory가 훨씬 개선되서 Calendar의 상수(YEAR, MONTH, DAY_OF_MONTH, DAY_OF_WEEK, HOUR, MINUTE, SECOND)를 전부 1부터 시작하게 만들 수도 있었을 것이다. 하지만 Java designer는 MONTH는 배열 형식으로 자주 쓰인다고 판단하여 배열과 마찬가지로 0부터 시작하게 만들어 편의성을 도모했다고 한다.
위 추측이 사실이든 designer본인만 알고 있는 다른 이유가 있었든 현재 시점에선 java.time을 사용하는게 error방지와 성능 양쪽에서 좋다는 것이 결론이다. 추후 경력이 쌓이고 대학원을 가서 더 공부하게 된다면 다시 알아보고 싶은 흥미로운 주제다.