12장: 날짜와 시간 API
자바의 새로운 날짜, 시간 클래스를 알아본다.
기존 자바의 날짜와 시간 API
자바 1.0부터 제공된 Date의 경우 특정 시점을 날짜가 아닌 밀리초 단위로 표현하며, 1900년을 기준으로 하는 오프셋, 달을 나타낼 때 0부터 시작하는 인덱스 등으로 인해 유용성이 떨어졌다.
2017년 9월 21일을 나타내려면 아래와 같이 작성해야하므로 직관적이지 않다.
자바 1.1에서 Calendar 클래스가 제공되었지만 여전히 달을 나타낼 때 0으로 시작하는 인덱스 문제가 있었고 오히려 DateFormat같은 일부 기능은 Date 클래스에만 작동했다.
DateFormat은 thread safe 하지 않아 두 스레드가 동시에 하나의 포매터로 날짜를 파싱하면 문제가 발생할 수 있다.
Date와 Calendar는 가변 클래스이기 때문에 다른 곳에서 의도치 않게 수정이 가능하므로 유지보수가 어려워질 수 있다.
새로운 날짜와 시간 API
LocalDate
시간을 제외한 날짜를 표현하는 불변 객체
어떤 시간대 정보도 포함하지 않는다.
아래와 같이 생성하고 값을 조회할 수 있다.
TemporalField를 이용해서 조회하는 방법도 있다.
LocalTime
시간을 나타내는 클래스
아래와 같이 생성하고 값을 조회할 수 있다.
LocalDateTime
LocalDate와 LocalTime을 쌍으로 가져 날짜와 시간을 모두 표현할 수 있다.
아래와 같이 생성할 수 있다.
LocalDate 혹은 LocalTime으로 추출할 수 있다.
Instant
인간 관점이 아닌 기계적인 관점에서 시간을 표현하는 클래스
unix epoch time(1970년 1월 1일 0시 0분 0초 UTC) 기준으로 특정 지점까지의 시간을 초로 나타낸다.
나노초 단위의 정밀도를 제공한다.
아래와 같이 생성할 수 있다. 두번째 인자를 통해 나노초 단위로 시간을 보정할 수 있다.
Duration
두 시간 객체 사이의 지속 시간을 나타내는 클래스
정적 팩토리 메서드인 between 메서드에 두 시간 객체를 입력하여 Duration 객체를 생성할 수 있다. 단, 두 객체의 타입은 같아야 한다.
of나 ofXXX 메서드도 제공하여 다양한 방식으로 객체를 만들 수 있다.
초, 나노초 단위로 시간을 표현하기 때문에 년,월,일 단위로는 Duration을 만들 수 없다.
Period
두 시간 객체 사이의 날짜를 나타내는 클래스
년,월,일 단위로 시간을 표현할 수 있다.
of나 ofXXX 메서드도 제공하여 다양한 방식으로 객체를 만들 수 있다.
날짜 조정, 파싱, 포매팅
기존 클래스로부터 새로운 클래스 생성
자바의 새로운 날짜와 시간 클래스들은 모두 불변이다. 대신 기존 객체에 값을 변경하여 새로운 객체를 만들어내는 메서드를 제공하여 편리하게 사용할 수 있다.
withXXX
메서드를 제공하여 기존의 LocalDate 객체에서 특정 값만 변경하여 새로운 LocalDate 객체를 반환한다.내부의 변수를 바꾸는 것이 아닌 새로운 객체를 반환하는 것이므로 새로운 변수에 할당해주어야 한다.
첫번째 인수로 TemporalField를 입력할 수도 있다.
지정된 시간을 추가하거나 뺄 수도 있다.
TemporalAdjusters
다음주 일요일, 돌아오는 평일 등 복잡한 날짜 조정 기능을 정적 메서드로 제공하는 클래스이다.
method | description |
---|---|
dayOfWeekInMonth | 서수 요일에 해당하는 날짜를 반환 |
firstDayOfMonth | 현재 달의 첫 번쨰 날짜를 반환 |
firstDayOfNextMonth | 다음 날의 첫 번째 날짜를 반환 |
firstDayOfNextYear | 내년의 첫 번째 날짜를 반환 |
firstDayOfYear | 올해의 첫 번째 날짜를 반환 |
firstInMonth | 현재 달의 첫 번째 요일에 해당하는 날짜를 반환 |
lastDayOfMonth | 현재달의 마지막 날짜를 반환 |
lastDayOfNextMonth | 다음 달의 마지막 날짜를 반환 |
lastDayOfNextYear | 내년의 마지막 날짜를 반환 |
lastDayOfYear | 올해의 마지막 날짜를 반환 |
lastInMonth | 현재 달의 마지막 요일에 해당하는 날짜 반환 |
next / previous | 현재 달에서 현재 날짜 이후로 지정한 요일이 처음으로 나타나는 날짜를 반환 |
nextOrSame / previousOrSame | 현재 날짜 이후로 지정한 요일이 처음 / 이전으로 나타나는 날짜를 반환 |
커스텀 TemporalAdjuster도 구현 가능하다.
DateTimeFormatter
정적 팩토리 메서드와 상수를 이용해 포매터를 만들 수 있다.
아래와 같이 포매터를 이용해 날짜 객체를 문자열으로 만들 수 있다.
혹은 문자열을 파싱해 객체로 만들 수 있다.
원하는 패턴을 입력하여 포매터를 사용할 수 있다.
Locale 정보를 넣어 국가별 최적화된 포매터도 만들어 사용할 수 있다.
parseCaseInsensitive()
를 통해 정해진 형식과 정확히 일치하지 않는 입력을 해석할 수 있도록 한다.
시간대
ZoneId
새로운 날짜와 시간 API의 편리함 중 하나는 시간대를 간단하게 처리할 수 있다는 점이다.
기존 TimeZone을 대체할 수 있는 ZoneId 클래스가 새롭게 등장했다.
새로운 클래스를 이용하면 서머타임같은 복잡한 사항이 자동으로 처리된다.
ZoneRules 클래스에 40여개의 시간대가 있다.
기존의 TimeZone 객체에서 toZoneId 메서드를 사용해 ZoneId 객체를 얻을 수 있다.
LocalDateTime을 비롯한 클래스들을 ZonedDateTime으로 변경할 수 있다.
ZoneOffset
UTC / GMC 기준으로 시간대를 표현하기 위해 ZoneOffset 클래스를 사용할 수 있다.
ISO-8601 외의 캘린더 시스템
전세계적으로 통용되는 ISO-8601 캘린더 시스템 외에 ThaiBuddhistDate, MinguoDate, JapaneseDate, HijrahDate를 제공한다.
Last updated