자바 개발을 하다 보면 날짜와 시간을 다루는 일이 빈번하다. 과거의 Date나 Calendar 클래스는 설계 결함이 많아 사용하기 매우 까다로웠으나, 자바 8에서 도입된 java.time 라이브러리는 이를 완벽하게 해결했다.
한눈에 보는 날짜와 시간 클래스 체계
자바가 제공하는 클래스들은 ‘무엇을 관리하느냐’에 따라 명확하게 구분된다. 아래 표는 자바 공식 문서를 기반으로 재구성한 핵심 요약이다
| 클래스 | 연 | 월 | 일 | 시 | 분 | 초 | 오프셋 | 존 ID | 비고 |
| LocalDate | V | V | V | 날짜만 (2023-08-20) | |||||
| LocalTime | V | V | V | 시간만 (08:16:26.943) | |||||
| LocalDateTime | V | V | V | V | V | V | 날짜+시간 (2023-08-20T08:16) | ||
| ZonedDateTime | V | V | V | V | V | V | V | V | 타임존 포함 (Asia/Seoul) |
| OffsetDateTime | V | V | V | V | V | V | V | UTC와의 차이만 기록 | |
| Instant | V | 기계 중심의 시각 (Epoch Time) | |||||||
| Period | V | V | V | 날짜 간격 (10일 동안) | |||||
| Duration | V | V | V | 시간 간격 (20시간 동안) |
기본 날짜와 시간 – Local 계열
LocalDate, LocalTime, LocalDateTime 클래스의 공통점은 이름 앞에 Local이 붙는다는 점이다
- Local의 의미: “현지의”, “특정 지역의”라는 뜻이다. 즉, 세계 시간대(타임존)을 고려하지 않는 날짜와 시간을 의미한다
- 사용 사례
- 국내 서비스만 개발하여 타임존 계산이 필요 없을 때
- 생일(yyyy-MM-dd)이나 기념일처럼 타임존과 무관하게 고정된 날짜 정보를 다룰 때
- 정밀도: ‘초’ 단위에는 밀리초(ms)와 나노초(ns)까지 포함되어 매우 정밀한 캡처가 가능하다
시간대를 고려한 날짜와 시간 – Zoned & Offset
글로벌 서비스를 개발한다면 전 세계의 시간 차이를 고려해야 한다. 이때 사용하는 것이 ZonedDateTime과 OffsetDateTime이다
ZonedDateTime – 타임존의 끝판왕
- 구성: LocalDateTime + Zone Offset + Zone Id
- 특징: Asia/Seoul과 같은 구체적인 타임존 ID를 포함한다
- 핵심 이점: 일광 절약 시간제(DST, 서머타임)를 자동으로 처리한다. 특정 지역의 규칙을 알고 있기 때문에, 서머타임 적용 시점에 시간이 변하는 로직을 자바가 알아서 계산해준다
OffsetDateTime – 고정된 차이만 고려
- 구성: LocalDateTime + Zone Offset
- 특징: UTC(협정 세계시)로부터 몇 시간 차이가 나는지(예: +09:00)만 기록한다. 타임존 ID가 없으므로 일광 절약 시간제가 적용되지 않는다
- 사용 사례: 시스템 간의 데이터 전송, 로그 기록 등 일광 절약 시간제의 복잡한 계산 없이 고정된 시간 차이만 유지해야 할 때 유용하다
기계 중심의 시간 – Instant
Instant는 사람이 읽는 날짜 형식이 아닌, 컴퓨터가 이해하기 쉬운 시간의 한 지점을 나타낸다
- 기준: 1970년 1월 10일 00:00:00(UTC)를 기준으로 경과한 시간을 ‘초’ 데이터(나노초 포함)로 관리한다. 이를 Epoch Time이라고도 한다
- 특징: 전 세계 어디서나 동일한 값을 가지는 절대적인 시간이다. 따라서 날짜 계산이나 비즈니스 로직보다는 로그 기록, 실행 시간 측정, 데이터베이스 저장 등에 적합하다
시간의 양 – Period vs Duration
자바에서는 ‘특정 시간’과 ‘시간의 간격’을 명확히 구분한다. 시간의 간격은 영어로 Amount of Time(시간의 양)이라고 부른다
Period (날짜의 간격)
- 단위: 년, 월, 일
- 예시: “이 프로젝트는 완료까지 3개월 남았다.”
- 사용: 두 날짜 사이의 차이를 구할 때 사용한다
Duration (시간의 간격)
- 단위: 시, 분, 초 (나노초 포함)
- 예시: “라면은 3분 동안 끓여야 맛있습니다”, “작업이 10시간 걸렸네요”
- 사용: 두 시간 사이의 차이를 구할 때 사용한다
어떤 클래스를 선택해야 할까?
- 타임존이 필요 없는 단순 정보: 날짜만 이면 LocalDate, 시간만 이면 LocalDateTime 사용
- 사용자에게 보여줄 실제 시간(글로벌 서비스): 서머타임 처리가 가능한 ZonedDateTime이 가장 안전하다
- 로그 기록 및 시스템 간 시간 동기화: OffsetDateTime이나 Instant를 권장한다
- 기간 계산: 날짜 차이는 Period, 시간 차이는 Duration으로 명확히 구분하여 코드의 가독성을 높일 수 있다