[Java] 날짜, 시간 API
😎 서론
최근 LocalDateTime과 같이 날짜나 시간과 관련한 로직을 작성할 일이 많았다. ZoneOffSet? Instant? 부끄럽게도 뭐가 뭔지 모르고 사용했던 것들이 많아 이를 알아보는 시간을 가지려 한다.🙂
😊 Java의 날짜와 시간 API
🔹 time 패키지
- ISO 기반 (24시간 시계 시스템 hh:mm:ss)
- 불변 + thread-safe
🔹 LocalDate / LocalTime / LocalDateTime
- 시간대 (ZoneOffset, ZoneRegion)에 대한 정보 미포함
- LocalDate: 날짜에 대한 정보
- LocalTime: 시간에 대한 정보
- LocalDateTime: 날짜 및 시간에 대한 정보
- `Local... `는 ZoneOffset과 ZoneRegion를 포함하지 않음
🔹 ZoneOffset
- UTC 기준의 시간
- ex: 우리나라는 UTC +09:00으로 표기
🔹 ZoneRegion
- 타임존
- ex: 우리나라는 Asia/Seoul 사용
🔻 ZoneOffset vs ZoneRegion
언뜻 보기에는 UTC +09:00와 Asia/Seoul을 볼 때 차이가 없는 것처럼 느껴진다. 이 둘은 왜 분리하여 사용할까? 이 이유는 DST(Daylight saving time; 써머 타임) 같은 Time Transition Rule 포함 여부 때문이다.
ZoneOffset | ZoneRegion | |
Time Transition Rule | 미포함 | 포함될 수도 있음 |
🔹 OffsetDateTime
- LocalDateTime + ZoneOffset
🔹 ZonedDateTime
- LocalDateTime + ZoneOffset + ZoneRegion
- 서머 타임과 같은 Time Transition Rule을 내부적으로 계산함 (ZoneRules라는 클래스 이용)
🔹 Instant
- unix timestamp를 구할 때 사용
- 어느 순간(시간)을 나타내는 클래스
- 1970년 1월 1일 UTC의 첫 번째 순간 이후 현재 시간까지의 나노초
🤔 왜 써야해요?
❓ java 1에서도 날짜, 시간 API는 있다
위에서 설명한 API들은 java 8부터 제공된다. 하지만 jdk 1버전부터 시간 관련 API인 Date, Calendar가 이미 존재해왔다. 왜 이미 있는걸 java 8에서 또 만들었을까? 결론부터 말하자면 Date와 Calendar는 불변 객체가 아니다. 멀티 스레드를 사용하는 경우 특정 스레드에서 데이터가 변경될 때 다른 스레드에까지 영향을 끼칠 수 있다는 문제가 있다.
📑 관련 포스팅
❓ Instant를 왜 쓸까?
timestamp는 언뜻 보기에 이런 이상한 숫자처럼 보인다. (ex: 1657087057.056339) 언뜻 보기에는 어떤 날짜를 의미하는지 알 수도 없는데 Instant를 왜 써야할까? 바로 연산 속도가 빠르기 때문이다. Instant는 long형의 seconds, int형의 nanos 두 가지 필드가 있다. long형과 int형을 통해 LocalDateTime보다 더 빠른 연산을 할 수 있다.
참고