본문 바로가기

책리뷰/모던자바인액션

모던자바인액션 12강 Date, Calendar 날짜와 시간 API

728x90
반응형

❓ 기존 자바에서 날짜 표현

자바 1.0에서는 java.util.Date클래스 하나로 날짜와 시간 기능을 제공했다. Date클래스는 밀리초단위로 표현이 된다.

Date date = new Date(117, 8, 21);
// 출력 결과 
Thu Sep 21 00:00:00 CET 2017

Date클래스의 출력은 직관적이지 않고 JVM기본 시간대인 CET 즉, 중앙 유럽시간대를 사용했다. 

 

자바 1.1에서 Date클래스의 대안으로 java.util.Calendar클래스를 제공했다.

하지만 Calendar역시 달의 인덱스는 0부터 시작하는 등의 설계 문제가 있었다.

 

DateFormat같은 일부 기능을 제공했지만 Date클래스에만 작동했기에 개발자들에게 더 혼란을 가중시켰다.

DateFormat은 스레드에 안전하지 않아서 문제의 요지가 있다.

 

부실한 날짜와 시간라이브러리 때문에 Joda-Time같은 서드파티 라이브러리를 사용하기 시작하자

오라클은 java.time패키지에 Joda-Time의 많은 기능을 추가했다.

 

 

 

⚫ LocalDate, LocalTime, Instant, Duration, Period클래스

LocalDate 

새로운 날짜와 시간 API를 사용할 때 처음 접하게 되는 것으로 시간을 제외한 날짜를 표현하는 불변객체다.

정적 팩토리 메서드 of로 Local인스턴스를 생성할 수 있다. 

LocalDate today = LocalDate.now();

팩토리 메서드 now는 시스템 시계의 정보를 이용해서 현재 날짜 정보를 얻는다. 

get 메서드에 TemporalField를 전달해서 정보를 얻을 수 있다. 

LocalDate date = LocalDate.parse("2017-09-21");
LocalTime time = LocalTime.parse("13:45:21");

parse메서드에 DateTimeFormatter를 전달할 수도 있다. 

LocalDateTime을 직접 만들 수도 있고 날짜와 시간을 조합할 수도 있다.

 

⚫ Instant 클래스 기계의 날짜와 시간

기계 관점에서 연속된 시간에서 특정지점을 하나의 큰수로 표현하는 것이 자연스러운 시간 표현 방법이다.

java.time.Instant 클래스에서는 유닉스 에포크 시간(1970년 1월 1일 0시 0분 0초 UTC)을 기준으로 특정지점까지의 시간을 초로 표현한다. 

Instant 클래스도 사람이 확인할 수 있도록 시간을 표시해주는 정적 팩토리 메서드 now를 제공한다. 

하지만 기계전용 유틸리티로 초와 나노초 정보를 포함한다. 

그러므로 사람이 읽을 수 있는 시간 정보를 제공하지 않는다.

Duration과 Period 클래스와 함께 활용 가능하다.

 

 

⚫ Duration 과 Period

Duration 👉🏻 Duration 클래스의 정적 팩토리 메서드 between으로 두 시간 객체 사이의 지속 시간을 만들 수 있다.

Duration d1 = Duration.between(time1, time2);
Duration d2 = Duration.between(dateTime1, dateTime2);
Duration d3 = Duration.between(instant1, instant2);

 

LocalDateTime은 사람이 사용, Instant는 기계가 사용하도록 만들어진 클래스로 두 인스턴스는 혼합 ❌

Duration클래스는 초와 나노초 시간 단위를 표현하기 때문에 between메서드에 LocalDate를 전달할 수 없다.

 

Period 👉🏻년, 월, 일로 시간 표현할 때 

Period tenDays = Period.between(LocalDate.of(2017, 9, 11), LocalDate.of(2017, 9, 21));

 

⚫ 날짜조정, 파싱, 포매팅

withAttribute메소드는 새로운 객체를 반환하는 메서드를 만들 수 있다.

절대적인 방식으로 LocalDate의 속성 바꾸기
상대적인 방식으로 LocalDate 속성바꾸기 
특정 시점을 표현하는 날짜 시간 클래스의 공통 메서드


⚫ TemporalAdjusters

다음 주 일요일, 돌아오는 평일, 어떤 달의 마짐작 날 등 복잡한 날짜 조정이 필요할 때 사용한다.

TemporalAdjuster를 이용하면 좀 더 복잡한 날짜 조정 기능을 직관적으로 해결할 수 있다.


⚫ 날짜와 시간 객체 출력과 파싱

포매팅과 파싱 전용패키지 java.time.format이 새로 추가 되었다.

DateTimeFormatter가 가장 중요한 클래스인데 정적 팩터리 메서드와 상수를 이용해서 쉽게 포매터를 만들 수 있다.

DateTimeFormatter는 스레드에서 안전하게 사용할 수 있는 클래스다.

 

 

특정 패턴으로 포매터를 만들 수 있는 정적 팩토리 메서드도 제공한다.

DateTimeFormatterBuilder클래스로 좀 더 세부적으로 포매터를 제어할 수 있다.


⚫ 시간대 사용하기

표준시간이 같은 지역을 묶어서 시간대 규칙 집합을 정의한다.

ZoneRules클래스에는 40개 정도의 시간대가 있다.

ZoneId의 getRules를 이용해서 해당 시간대의 규정을 획득할 수 있다. 

ZoneId romeZone = ZoneId.of("Europe/Rome");

지역ID는 {지역}/{도시} 형식으로 이루어진다.

IANA Time Zone Database에서 제공하는 지역 집합 정보를 사용한다.

ZoneId zoneId = TimeZone.getDefault().toZoneId();

toZoneId로 기존 TimeZone객체를 ZoneId객체로 변환할 수 있다. 

Instant instant = Instant.now();
LocalDateTime timeFromInstant = LocalDateTime.ofInstant(instant, romeZone);

ZoneId를 이용해서 LocalDateTime을 Instant로 바꿀 수도 있다.

 

728x90
반응형