날짜와 시간 라이브러리
- 날짜와 시간 차이 계산
- 윤년 계산
- 일광 절약 시간(DST)
- 타임존 계산
위와 같은 이유로 날짜와 시간을 계산하는 것은 매우 어렵고 복잡하다
GMT (그리니치 평균 시)
영국 런던의 그리니치 천문대를 태양이 통과할 떄를 정오로 한다
UTC (협정 세계 시)
GMT 를 대체하기 위해 도입되었다
UTC 와 GMT 모두 그리니치 천문대를 기준으로 하지만
UTC 는 원자 시계를 사용하여 측정한 시간 체계다
지구 자전 속도가 변화하는 것을 고려하여 윤초를 적용한 시간을 사용함으로
정확한 시간을 유지한다
일반적으로는 GMT 와 UTC 는 큰 차이를 보이지 않지만
국제 표준에 UTC 가 선호된다
예전의 자바에서는 Date, Calendar 라는 자체 라이브러리를 제공하였으나
사용성이 떨어지고 문제가 있었다
이를 대체하기 위해 오픈소스인 Joda-Time 이 등장하였고
편리함과 사용성을 기반으로 대중화 되었다
자바는 Joda-Time 의 개발자를 데려와 java.time 이라는
자바 표준 라이브러리를 새로 정의하였다
java.time

- *: 초는 나노초 단위의 정밀도로 캡처된다 (밀리초, 나노초 가능)
- **: 이 클래스는 이 정보를 저장하지 않지만 이런 단위로 시간을 제공하는 메서드가 있다
- ***: ZonedDateTime 에 Period 를 추가하면 서머타임 및 현지 시간 차이를 준수한다
Local
- LocalDate: 날짜만 표현할 때
- LocalTime: 시간만 표현할 때
- LocalDateTime: LocalDate 와 LocalTime 모두 표현할 때
Local 은 세계 시간을 고려하지 않아 타임 존이 적용되지 않는다
특정 지역의 날짜와 시간만 고려할 때 사용한다
- 특정 지역의 국내 서비스만 고려 시
- 해당 지역에서의 날짜나 시간을 일회성으로 사용 시
Zoned, Offset
- ZonedDateTime: 시간대를 고려한 날짜와 시간 표현 (타임존 포함)
- offset: UTC (협정 세계시)로 부터의 시간 차이를 나타낸다 +9:00 이면 협정 세계시 부터 +9 시간
- OffsetDateTime: 시간대를 고려한 날짜와 시간 표현, 타임존은 없지만 UTC로부터의 시간 차이인 고정 ofsset 만 포함
Instant
UTC 를 기준으로 하는 시간의 한 지점을 나타낸다
날짜와 시간을 나노초 정밀도로 표현하는 초 데이터만 들어있다
1970년 1월 1일 0시 0분 0초 (UTC) 기준으로 경과한 시간으로 계산
시간대에 영향을 받지 않는 절대적인 시간 표현 방식
Epoch time
Epoch time 또는 Unix timestamp 는 컴퓨터 시스템에서 시간을 나타내는 방법 중 하나
UTC 부터 현재까지의 시간을 초 단위로 표현한 것
Instant 는 Epoch time 을 다루는 클래스
Period, Duration
시간 개념은 크게 2가지
- 특정 시점의 시간 (시각)
- 시간의 간격 (기간)
Period, Duration 은 기간을 표현할 때 사용
기간은 영어로 amount of time 으로 불린다
Period
두 날짜 사이의 간격을 년, 월, 일 단위로 나타낸다
- getYears(), getMonths(), getDays()
Duration
두 시간 사이의 간격을 시, 분 초(나노초) 단위로 나타낸다
- toHours(), toMinutes(), getSeconds(), getNano()
날짜와 시간 핵심 인터페이스
`<interface>`
TemporalAccessor
|
`<interface>`
Temporal
|
LocalDate Time, ZonedDateTime, Instant
`<interface>`
TemporalAmount
|
Period, Duration
TemporalAccessor 인터페이스
- 날짜와 시간을 읽기 위한 기본 인터페이스
- 특정 시점의 날짜, 시간 정보를 읽을 수 있는 최소한의 기능 제공
Temporal 인터페이스
TemporalAccessor 의 하위 인터페이스로 날짜와 시간을 조작하기 위한 기능을 제공
TemporalAmount
시간의 간격 (시간의 양, 기간)을 나타내며, 날짜와 시간 객체를 조정할 수 있다
시간의 단위와 시간 필드
`<interface>`
TemporalUnit
|
CronoUnit
`<interface>`
TemporalField
|
CronoField
날짜와 시간의 핵심 인터페이스는
시간위 단위를 뜻하는 TemporalUnit 과
시간의 각 필드를 뜻하는 TemporalField 가 있다
시간의 단위 - TemporalUnit, ChronoUnit
- TemporalUnit 인터페이스는 날짜와 시간을 측정하는 단위를 나타내며, 주로 사용되는 구현체는 java.time.temporal.ChronoUnit 열거형으로 구현되어 있다
- ChronoUnit 은 다양한 시간 단위를 제공한다
ChronoUnit
시간 단위
- NANOS: 나노초
- MICROS: 마이크로초
- MILLIS: 밀리초
- SECONDS: 초
- MINUTES: 분
- HOURS: 시간
날짜 단위
- DAYS: 일
- WEEKS: 주
- MONTHS: 월
- YEARS: 년
- DECADES: 10년
- CENTURIES: 세기
- MILLENNIA: 천 년
주요 메서드
- between(Temporal, Temporal): 두 Temporal 객체 사이의 시간을 현재 ChronoUnit 단위로 측정하여 반환
- isDateBased(): 현재 ChronoUnit 이 날짜 기반 단위인지 여부
- isTimeBased(): 현재 ChronoUnit 이 시간 기반 단위인지 여부
- isSupportedBy(Temporal): 주어진 Temporal 객체가 현재 ChronoUnit 단위를 지원하는지 여부
- getDuration(): 현재 ChronoUnit 기간을 Duration 객체로 반환
시간 필드 - ChronoField
날짜 및 시간을 나타내는 데 사용되는 열거형
날짜와 시간의 특정 부분을 나타낸다 - 연도, 월, 일, 시간, 분 등이 포함
- TemporalFeild 인터페이스는 날짜와 시간을 나타내는데 사용된다
주로 사용되는 구현체는 java.time.temporal.ChronoField
- ChronoField 는 다양한 필드를 통해 날짜와 시간의 특정 부분을 나타낸다
- 단순히 시간 단위 하나하나를 뜻하는 ChronoUnit 과는 다르게 날짜와 시간의 필드 중 우너하는 데이터를 조회할 수 있다
ex) 2024년 8월 16일의 필드
- YEAR: 2024
- MONTH_OF_YEAR: 8
- DAY_OF_MONTH: 16
연도 필드
- ERA: 연대
- YEAR_OF_ERA: 연대 내 연도
- YEAR: 연도
- EPOCH_DAY: 1970-01-01 부터의 일 수
월 필드
- MONTH_OF_YEAR: 월
- PROLEPTIC_MONTH: 연도를 월로 확정한 값
주 및 일 관련 필드
- DAY_OF_WEEK: 요일 (월요일 = 1)
- ALIGNED_DAY_OF_WEEK_IN_MONTH: 월의 첫 번째 요일을 기준으로 정렬된 요일
- ALIGNED_DAY_OF_WEEK_IN_YEAR: 연의 첫 번째 요일을 기준으로 정렬된 요일
- DAY_OF_MONTH: 월의 일 (1일 = 1)
- DAY_OF_YEAR: 연의 일 (1월 1일 = 1)
- EPOCH_DAY: 유닉스 에폭(1970-01-01) 부터의 일 수
시간 관련 필드
- HOUR_OF_DAY: 시간 (0-23)
- CLOCK_HOUR_OF_DAY: 시계 시간 (1~24)
- MINUTE_OF_HOUR: 분
- SECOND_OF_MINUTE: 초
- NANO_OF_SECOND: 나노초
기타 필드
- APPM_OF_DAY: 하루의 AM/PM
- INSTANT_SECONDS: 초 기준 한 시간
- OFSET_SECONDS: UTC/GMT 에서의 시간 오프셋 초