6. 날짜와 시간

날짜와 시간 라이브러리가 필요한 이유

날짜와 시간을 계산하는 것은 단순하게 생각하면 쉬워보이지만, 실제로는 매우 어렵고 복잡하다.

1. 날짜와 시간 차이 계산

특정 날짜에서 다른 날짜까지의 정확한 일수를 계산하는 것은 생각보다 복잡하다. 윤년, 각 달의 일수 등을 모두 고려해서 계산하는 것은 쉽지 않다.

2. 윤년 계산

지구가 태양을 한바퀴 도는 시간과 1년 365일의 차이가 있기 때문에, 4년마다 하루를 추가하는 윤년을 도입한다. 하지만 그 윤년에도 다양한 예외사항이 있기 때문에, 계산하는 것이 쉬운일이 아니다.

3. 일광 절약 시간 변환

보통 3월에서 10월은 태양이 일찍 뜨고, 나머지는 상대적으로 태양이 늦게 뜬다. 시간도 여기에 맞추어 1시간 앞당기거나 늦추는 제도를 일과 절약 시간제 또는 썸머 타임이라고 한다. 일광 절약 시간은 국가나 지역에 따라 적용 여부와 시작 및 종료 날짜가 다르다. 이와 같은 예외사항으로 정확하게 계산하는 것은 매우 어렵다.

참고로 대한민국은 1988년 이후로 시행하지 않는다.

4. 타임존 계산

세계는 다양한 타임존으로 나뉘어 있으며, 각 타임존은 UTC(협정 세계시) 로부터의 시간 차이로 정의된다. 타임존 간의 날짜와 시간 변환을 정확히 계산하는 것은 복잡하다.

결론

이러한 복잡성 때문에 대부분의 현대 개발 환경에서는 날짜와 시간을 처리하기 위해 잘 설계된 라이브러리르를 사용해야 한다.

자바 날짜와 시간 라이브러리 역사

JDK 1.0(java.util.Date)

  • 문제점

    • 타임존 처리 부족

    • 불편한 날짜 시간 연산

    • 불변 객체 부재

  • 해결책

    • JDK 1.1 에서 java.util.Calendar 클래스 도입으로 타임존 지원 개선

    • 날짜 시간 연산을 위한 추가 메서드 제공

JDK 1.1(java.util.Calendar)

  • 문제점

    • 사용성 저하

    • 성능 문제

    • 불변 객체 부재

  • 해결책

    • Joda-Time 오픈소스 라이브러리 도입으로 사용성, 성능, 불변성 문제 해결

Joda-Time

  • 문제점

    • 표준 라이브러리가 아님

  • 해결책

    • 자바 8에서 java.time 패키지를 표준 API 로 도입

JDK 8 (java.time 패키지)

  • java.time 패키지는 이전 API 문제를 해결하면서, 사용성, 성능, 스레드 안전성, 타임존 처리 등에서 크게 개선되었다.

  • LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant 등의 클래스를 포함한다.

  • Joda-Time 의 많은 기능을 표준 플랫폼으로 가져왔다.

자바 날짜와 시간 라이브러리 소개

자바 날짜와 시간 라이브러리는 자바 공식 문서가 제공하는 다음 표 하나로 정리할 수 있다.

LocalDate, LocalTime, LocalDateTime

  • LocalDate : 날짜만 표현할 때 사용한다.

  • LocalTime : 시간을 표현할 떄 사용한다.

  • LocalDateTime : LocalDate, LocalTime 을 합한 개념이다.

앞에 Local (현지의, 특정 지역의) 이 붙는 이유는 세계 시간대를 고려하지 않아서 타임존이 적용되지 않기 때문이다. 특정 지역의 날짜와 시간만 고려할 때 사용한다.

  • 애플리케이션 개발시 국내 서비스만 고려할 때

ZonedDateTime, OffsetDateTime

  • ZonedDateTime : 시간대를 고려한 날짜와 시간을 표현할 때 사용한다. 여기에는 시간대를 표현하는 타임존과 오프셋이 포함된다.

  • OffsetDateTime : 시간대를 고려한 날짜와 시간을 표현할 때 사용한다. 여기에는 타임존이 없고, UTC 로 부터의 시간대 차이가 고정인 오프셋만 포함된다.

Asia/Seoul 과 같은 타임존 안에는 일광 절약 시간제에 대한 정보와 UTC+9:00와 같은 UTC 로 부터 시간 차이인 오프셋 정보를 모두 포함하고 있다.

일광 절약 시간제를 알려면 타임존을 알아야 한다. 따라서 ZonedDateTime 은 일광 절약 시간제를 함께 처리한다. 반면에 타임존을 알 수 없는 OffsetDateTime 은 일광 절약 시간제를 처리하지 못한다.

Instant

Instant 는 UTC 를 기준으로 하는, 시간의 한 지점을 나타낸다. Instant 는 날짜와 시간을 나노초 정밀도로 표현하며, 1970. 1. 1 00:00:00 를 기준으로 경과한 시간이 계산된다.

쉽게 이야기해서 Instant 내부에는 초 데이터만 들어있다. 따라서 날짜와 시간을 계산하는 용도로는 적합핮지 않다.

Period, Duration

시간의 개념은 크게 2가지로 표현할 수 있다.

  • 특정 시점에 시간(시각)

    • 이 프로젝트는 2013년 8월 16일 까지 완료해야해

    • 다음 회의는 11시 30분에 진행한다.

    • 내 생일은 8월 16일이야.

  • 시간의 간격(기간)

    • 앞으로 4년은 더 공부해야 해

    • 이 프로젝트는 3개월 남았어

    • 라면은 3분 동안 끓어야 해

Period, Duration 은 시간의 간격(기간) 을 표현하는데 사용된다.

Period

두 날짜 사이의 간격을 년, 월, 일 단위로 나타낸다.

Duration

두 시간 사이의 간격을 시, 분, 초 단위로 나타낸다.

기본 날짜와 시간 - LocalDateTime

LocalDate

LocalTime

LocalDateTime

타임존 - ZonedDateTime

ZoneId

자바는 타임존을 ZoneId 클래스로 제공한다.

ZonedDateTime

ZonedDateTime 클래스

OffsetDateTime

OffsetDateTime 클래스

기계 중심의 시간 - Instant

Instant 클래스

Instant 특징

  • 장점

    • 시간대 독립성 : Instant 는 UTC 를 기준으로 하므로, 시간대에 영향을 받지 않는다. 이는 전 세계 어디서나 동일한 시점을 가리키는데 유용하다.

    • 고정된 기준점 : 모든 Instant 는 1970. 1. 1 UTC 를 기준으로 하기 때문에, 시간 계산 및 비교가 명확하고 일관된다.

  • 단점

    • 사용자 친화적이지 않다.

    • 시간대 정보 부재

  • 사용예

    • 전 시계적인 시간 기준 필요시 ..

    • 시간대 변환 없이 시간 계산 필요시 ..

    • 데이터 저장 및 교환

기간, 시간의 간격 - Duration, Period

Period

Duration

날짜와 시간의 핵심 인터페이스

핵심 인터페이스

  • 특정 지점의 시간 : Temporal(TemporalAccessor) 인터페이스를 구현한다.

    • 구현으로 LocalDateTime, LocalDate, LocalTime, ZonedDateTime, OffsetDateTime 등이 있다.

  • 시간의 간격(기간) : TemporalAmount 인터페이스를 구현한다.

    • 구현으로 Period, Duration 이 있다.

TemporalAccessor 인터페이스

  • 날짜와 시간을 읽기 위한 기본 인터페이스

  • 이 인터페이스는 특정 시점의 날짜와 시간 정보를 읽을 수 있는 최소한의 기능을 제공한다.

Temporal 인터페이스

  • TemporalAccessor 의 하위 인터페이스로, 날짜와 시간을 조작하기 위한 기능을 제공한다. 이를 통해서 날짜와 시간을 변경하거나 조정할 수 있다.

TemporalAmount 인터페이스

  • 시간의 간격을 나타내며, 날짜와 시간 객체에 적용하여 그 객체를 조정할 수 있다.

시간의 단위와 시간 필드 인터페이스

...

날짜와 시간 문자열 파싱과 포맷팅

Last updated