티스토리 뷰

728x90

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

LocalDate, LocalTime 사용

LocalDate 인스턴스는 시간을 제외한 날짜를 표현하는 불변 객체다. 특히 LocalDate 객체는 어떤 시간대 정보도 포함하지 않는다.

정적 팩토리 메서드 of로 LocalDate 인스턴스를 만들 수 있다.

LocalDate date = LocalDate.of(2022,03,01);

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

LocalDate today = LocalDate.now();

내장 메서드 getYear(), getMonthValue(), getDayOfMonth() 를 이용해서 시간 객체의 값을 알 수 있다.

LocalDate date = LocalDate.of(2014, 3, 18);
int year = date.getYear(); // 2014
Month month = date.getMonth(); // MARCH
int day = date.getDayOfMonth(); // 18
DayOfWeek dow = date.getDayOfWeek(); // TUESDAY
int len = date.lengthOfMonth(); // 31 (3월의 길이)

시간에 대한 클래스는 LocalTime 클래스로 표현할 수 있다. 두가지 정적 메서드 of로 LocalTime 인스턴스를 만들 수 있다.

시간과 분을 인수로 받는 of 메서드와 시간과 분, 초를 인수로 받는 of 메서드가 있다.

LocalTime time = LocalTime.of(13, 45, 20); // 13:45:20
int hour = time.getHour(); // 13
int minute = time.getMinute(); // 45
int second = time.getSecond(); // 20

날짜와 시간 문자열로 LocalDate와 LocalTime의 인스턴스를 만드는 방법

LocalDate date = LocalDate.parse("2022-03-01")
LocalTime time = LocalTime.parse("13:45:20");

날짜와 시간 조합

LocalDateTime은 LocalDate와 LocalTime을 쌍으로 갖는 복합 클래스이다. 즉, LocalDateTime은 날짜와 시간을 모두 표현할 수 있다.

LocalDate date = LocalDate.of(2014, 3, 18);
LocalTime time = LocalTime.of(13, 45, 20); // 13:45:20

LocalDateTime dt1 = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45, 20); // 2014-03-18T13:45
LocalDateTime dt2 = LocalDateTime.of(date, time);
LocalDateTime dt3 = date.atTime(13, 45, 20);
LocalDateTime dt4 = date.atTime(time);
LocalDateTime dt5 = time.atDate(date);

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

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

팩토리 메서드 ofEpochSecond에 초를 넘겨줘서 Instant 클래스 인스턴스를 만들 수 있다. Instant 클래스는 나노초(10억분의 1초)의 정밀도를 제공한다.

Instant.ofEpochSecond(3);
Instant.ofEpochSecond(3,0);

Instant 클래스도 사람이 확인할 수 있도록 시간을 표현해주는 정적 팩토리 메서드 now를 제공한다. 그냥 Instant는 기계 전용의 유틸리티라는 점을 기억.

Duration과 Period 정의

지금까지 살펴본 모든 클래스는 Temporal 인터페이스를 구현하는데, Temporal 인터페이스는 특정 시간을 모델링하는 객체의 값을 어떻게 읽고 조작할지 정의한다.

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

년, 월, 일로 시간을 표현할 때는 Period 클래스를 사용한다. 즉, Period 클래스의 팩토리 메서드 between을 이용하면 두 LocalDate의 차이를 확인할 수 있다.

Period tenDays = Period.between(LocalDate.of(2022, 3, 11),
                LocalDate.of(2022, 3, 21));

날짜 조정, 파싱, 포매팅

withAttribute 메서드로 기존의 LocalDate를 바꾼 버전을 직접 간단하게 만들 수 있다. 모든 메서드는 기존 객체는 바꾸지 않고 새로운 객체를 생성한다.

LocalDate date1 = LocalDate.of(2017, 9, 21); // 2017-09-21
LocalDate date2 = date1.withYear(2011); //2011-09-21
LocalDate date3 = date2.withDayOfMonth(25); //2011-09-25
LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 2); //2011-02-25

마지막 with 메서드 처럼 첫 번째 인수로 TemproalField를 갖는 메서드를 사용하면 좀 더 범용적으로 메서드를 활용할 수 있다. with 메서드는 get 메서드와 쌍을 이루며 이들 두 메서드는 날짜와 시간 API의 모든 클래스가 구현하는 Temporal 인터페이스에 정의되어 있다.

get과 with 메서드로 Temporal 객체의 필드값을 읽거나 고칠 수 있다. 어떤 Temporal 객체가 지정된 필드를 지원하지 않으면 UnsupprotedTemporalTypeException이 발생한다.

그리고 선언형으로 LocalDate를 사용하는 방법도 있다.

LocalDate date1 = LocalDate.of(2017, 9, 21); // 2017-09-21
LocalDate date2 = date1.plusWeeks(1); //2017-09-28
LocalDate date3 = date2.minusYears(6); //2011-09-28
LocalDate date4 = date3.plus(6,ChronoUnit.MONTHS); //2012-03-28

with와 get과 비슷한 plus,minus 메서드를 사용해서 Temporal을 특정 시간만큼 앞뒤로 이동시킬 수 있다.

TemporalAdjusters 사용하기

다음 주 일요일, 돌아오는 평일, 어떤 달의 마지막 날 등 좀 더 복잡한 날짜 조정 기능이 필요할 때는 TemporalAdjuster를 직접 전달하는 방법으로 문제를 해결할 수 있다.

날짜와 시간 API는 다양한 상황에서 사용할 수 있도록 다양한 TemporalAdjuster를 제공한다.

import static java.time.temporal.TemporalAdjusters.*;

LocalDate date = LocalDate.of(2014, 3, 18);
LocalDate date1 = date.with(nextOrSame(DayOfWeek.SUNDAY)); //2014-03-23
LocalDate date2 = date.with(lastDayOfMonth()); //2014-03-31

기능이 정의되어 있지 않을 때는 비교적 쉽게 커스텀 TemporalAdjuster 구현을 만들 수 있다.

@FunctionalInterface
public interface TemporalAdjuster {
    Temporal adjustInto(Temporal temporal);
}

TemporalAdjuster 인터페이스 구현은 Temporal 객체를 어떻게 다른 Temporal 객체로 변환할지 정의한다. 결국 TemporalAdjuster 인터페이스를 UnaryOperator과 같은 형식으로 간주할 수 있다.

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

날짜와 시간 관련 작업에서 포매팅과 파싱은 서로 떨어질 수 없는 관계다. 포매팅과 파싱 전용 패키지인 java.time.format 에서 가장 중요한 클래스는 DateTimeFormatter다.

정적 팩토리 메서드와 상수를 이용해서 손쉽게 포매터를 만들 수 있다.

LocalDate date = LocalDate.of(2014, 3, 18);

date.format(DateTimeFormatter.BASIC_ISO_DATE); //20140318
date.format(DateTimeFormatter.ISO_LOCAL_DATE); //2014-03-18

반대로 날짜나 시간을 표현하는 문자열을 파싱해서 날짜 객체를 다시 만들 수 있다. 날짜와 시간 API에서 특정 시점이나 간격을 표현하는 모든 클래스의 팩토리 메서드 parse를 이용해서 문자열을 날짜 객체로 만들 수 있다.

LocalDate date1 = LocalDate.parse("20140318", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate date2 = LocalDate.parse("2014-03-18", DateTimeFormatter.ISO_LOCAL_DATE);

기존의 java.util.DateFormat 클래스와 달리 모든 DateTimeFormatter는 스레드에서 안전하게 사용할 수 있는 클래스다.

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

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate date = LocalDate.of(2014, 3, 18);
String formattedDate = date1.format(formatter);
LocalDate date2 = LocalDate.parse(formattedDate, formatter);

LocalDate의 format 메서드는 요청 형식의 패턴에 해당하는 문자열을 생성한다. 그리고 정적 메서드 parse는 같은 포매터를 적용해서 생성된 문자열을 파싱함으로써 다시 날짜를 생성한다.

또한, DateTimeFormatterBuilder 클래스로 복합적인 포매터를 정의해서 원하는 포매터를 직접 만들 수 있다.

다양한 시간대와 캘린더 활용 방법

새로운 날짜와 시간 API의 큰 편리함 중 하나는 시간대를 간단하게 처리할 수 있다는 점이다. 기존의 java.util.TimeZone을 대체할 수 있는 java.time.ZoneId 클래스가 새롭게 등장했다.

날짜와 시간 API에서 제공하는 다른 클래스와 마찬가지로 ZoneId는 불변 클래스다.

시간대 사용하기

표준이 같은 지역을 묶어서 시간대(time zone) 규칙 집합을 정의한다. ZoneRules 클래스에는 약 40개 정도의 시간대가 있다. ZoneId의 getRules()를 이용해서 해당 시간대의 규정을 획득할 수 있다.

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

지역 ID는 '{지역}/{도시}' 형식으로 이루어 진다. getDefault() 메서드를 이용하면 기존의 TimeZone 객체를 ZoneId 객체로 변환할 수 있다.

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

ZoneId는 LocalDate, LocalTime, LocalDateTime과 같이 ZonedDateTime 인스턴스로 변환할 수 있다.

ZonedDateTime은 지정한 시간대에 상대적인 시점을 표현한다.

LocalDate date = LocalDate.of(2014, 13, 18);
ZonedDateTime zdt = date.atStartOfDay(romeZone);

LocalDate, LocalTime, LocalDateTime, ZoneId 의 차이

728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함