Modern Java Ch12. 날짜와 시간 API
자바 API는 복잡한 애플리케이션을 만드는 데 필요한 여러 가지 유용한 컴포넌트를 제공한다.
Date 클래스는 특정 시점을 날짜가 아닌 밀리초 단위로 표현한다.
Date date = new Date(117,8,21);
//결과값 - Thu Sep 21 00:00:00 CET 2017
결과가 직관적이지 않다.
12.1.1 LocalDate와 LocalTime의 사용
LocalDate 인스턴스는 시간을 제외한 날짜를 표현하는 불변 객체다.
LocalDate date = LocalDate.of(2017, 9, 11); //2017-09-11
int year = date.getYear();
Month month = date.getMonth();
int day = date.getDayOfMonth();
DayOfWeek dow = date.getDayOfWeek();
int len = date.lengthOfMonth();
boolean leap = date.isLeapYear();
- TemporalField는 시간 관련해서 어떤 필드의 값에 접근할 지 정의하는 인터페이스다.
int year = date.get(ChronoField.YEAR);
int month = date.get(ChronoField.MONTH_OF_YEAR);
int day = date.get(ChronoField.DAY_OF_MONTH);
시간도 LocalTime을 이용해 표현할 수 있다.
LocalTime time = LocalTime.of(13,45,20);
time.getHour();
time.getMinute();
time.getSecond();
string을 사용해 LocalTime.of("2017-09-21"); 인스턴스를 만들 수 있다.
날짜와 시간의 조합
LocalDateTime은 LocalDate와 LocalTime을 쌍으로 갖는 복합 클래스이다.
LocalDateTime dt1 = LocalDateTime.of(2017, Month.SEPTEMBER, 21, 13, 45, 20);
LocalDateTime dt2 = LocalDateTime.of(date, time);
LocalDateTime dt3 = date.atTime(13,45,20);
LocalDateTime dt4 = date.atTime(time);
LocalDateTime dt5 = time.atDate(date);
Instatnt 클래스
기계의 관점에서 연속된 시간에서 특정 지점을 하나의 큰 수로 표현하는 것이 가장 자연스러운 시간 표현 방법이다.
Instant 클래스는 에포크 시간(알아서 찾아보길) 기준으로 특정 지점까지의 시간을 초로 표현한다.
Instant.ofEpochSecond(3);
Instant.ofEpochSecond(3,0);
Instant.ofEpochSecond(2,1_000_000_000); //2초 이 후의 1억 나노초
Instant.ofEpochSecond(4,-1_000_000_000); //4초 이전의 1억 나노초
Duration과 Period의 정의
지금까지의 인터페이스는 Temporal 인터페이스를 구현한 것이다. Temporal 인터페이스는 특정 시간을 모델링하는 객체의 값을 어떻게 읽고 조작할 지 정의한다. Duration 클래스의 정적 팩토리 메서드 between으로 두 시간 객체 사이의 지속 시간을 만들 수 있다.
Duration d1 = Duration.between(time1, time2);
Duration d2 = Duration.between(dateTime1, dateTime2);
Duration d3 = Duration.between(instant1, instant2);
LocalDateTime은 사람이 사용하도록, Instant는 기계가 사용하도록 만들어진 클래스로 두 인스턴스는 서로 혼합될 수 없다.
Duration 클래스는 초와 나노초로 시간 단위를 표현하므로 between 메서드에 LocalDateTime을 전달할 수 없다.
년 월 일로 시간을 표현할 때는 Period 클래스를 사용한다. 즉, Period 클래스의 팩토리 메서드 between을 이용하면 두 LocalDate의 차이를 확인할 수 있다.
Period tenDays =Period.between(LocalDate.of(2017,9,11),LocalDate.of(2017,9,21) );
지금까짖 살펴본 모든 클래스는 불변이다. 불변 클래스는 함수형 프로그래밍 그리고 스레드 안전성과 도메인 모델의 일관성을 유지하는데 좋은 특징이다.
날짜 조정, 파싱, 포매팅
withAttribute - 절대적인 방식으로 LocalDate의 속성 바꾸기
LocalDate date1 = LocalDate.of(2017,9,21);
LocalDate date1 = date.withYear(2011);
LocalDate date1 = date.withDayIfMonth(25);
특정 시점을 표현하는 날짜 시간 클래스의 공통 메서드
TemporalAdjusters
다음주 월요일, 돌아오는 평일, 등 좀 더 복잡한 날짜 조정 기능이 있다.
import static java.time.temporal.TemporalAdjusters.*;
LocalDate date1 = LocalDate.of(2014, 3, 18);
LocalDate date2 = date1.with(nextOrSame(DayOfWeek.SUNDAY));
LocalDate date3 = date2.with(lastDayOfMonth());
메서드설명
dayOfWeekInMonth | 서수 요일에 해당하는 날짜를 반환하는 TemporalAdjuster를 반환함 |
firstDayOfMonth | 현재 달의 첫 번째 날짜를 반환 |
firstDayOfNextMonth | 다음 달의 첫 번째 날짜를 반환 |
firstDayOfNextYear | 내년의 첫 번째 날짜를 반환 |
firstInMonth | 올해의 첫 번째 날짜를 반환 |
lastDayOfMonth | 현재 달의 마지막 날짜를 반환 |
lastDayOfNextMonth | 다음 달의 마지막 날짜를 반환 |
lastDayOfNextYear | 내년의 마지막 날짜를 반환 |
lastDayOfYear | 올해의 마지막 날짜를 반환 |
lastInMonth | 현재 달의 마지막 요일에 해당하는 날짜를 반환 |
next previous | 현재 달에서 현재 날짜 이후로 지정한 요일이 청므으로 나타나는 날짜를 반환하는 TemporalAdjuster를 반환함 |
nextOrSame | 현재 날짜 이후로 지정한 요일이 처음으로 나타나는 날짜를 반환하는 TemporalAdjuster를 반환함 |
previousOrSame | 현재 날짜 이후로 지정한 요일이 이전으로 나타나는 날짜를 반환하는 TemporalAdjuster를 반환함 |
날짜와 시간 객체 출력과 파싱
날짜와 시간 관련 작업에서 포매팅과 파싱은 떨어질 수 없는 관계다.
LocalDate date = LocalDate.of(2014,4,18);
String s = date.format(DateTimeFormatter.BASIC_ISO_DATE); //20140418
String s = date.format(DateTimeFormatter.ISO_LOCAL_DATE); //2014-03-18
날짜와 시간을 표현하는 문자열을 파싱해 날짜 객체를 다시 만들 수 있다.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate date1 = LocalDate.of(2014, 3, 18);
String formattedDate = date1.format(formatter);
LocalDate date2 = LocalDate.parse(formattedDate, formatter);
DateTimeFormatterBuilder 클래스로 복합적인 포매터를 정의해서 좀 더 세부적으로 포매터를 제어할 수 있다.
즉, DateTimeFormatterBuilder 클래스로 대소문자를 구분하는 파싱, 관대한 규칙을 적용하는 파싱, 패딩, 포매터의 선택사항 등을 활용할 수 있다.
다양한 시간대와 캘린더 활용 방법
시간대 사용하기
표준 시간이 같은 지역을 묶어서 시간대(time zone) 규칙 집합을 정의한다.
ZoneRules 클래스에는 약 40개 정도의 시간대가 들어있다. ZoneId의 getRules()를 이용해서 해당 시간대의 규정을 획득할 수 있다. 다음처럼 지역 ID로 특정 ZoneId를 구분한다.
ZoneId romeZone = ZoneId.of("Europe/Rome");
'Study > Modern-Java-In-Action' 카테고리의 다른 글
Modern Java Ch15. completableFuture와 Reactive 프로그래밍 (0) | 2023.01.25 |
---|---|
Modern Java Ch13. Default Method (0) | 2023.01.24 |
Modern Java Ch11. Optional Class (0) | 2023.01.24 |
Modern Java Ch09. 리팩터링_테스팅_디버깅 (0) | 2023.01.24 |
Modern Java Ch08. 컬렉션 API 개선 (0) | 2023.01.24 |
댓글