LocalDate, LocalTime, LocalDateTime, ZonedDateTime 과 같은 API들은 java.util.Date, java.util.Calendar의 단점을 보완하기 위해 Java8에 추가되었다.
기존 (java.util.Date, java.util.Calendar) API의 단점
- Thread safe 하지 않다.
동시성 이슈(Concurrency issues)가 존재한다. - 향상된 설계와 이해가 용이하다.
Date와 Calendar API는 날짜 연산에 적합하지 않게 설계되었다. 새로운 API는 ISO 중심이고, 일관적인 날짜 시간, 기간 도메인 모델을 따르고, 다양한 편의 기능들을 제공한다. - 시간대 (시차) 처리가 불편하다.
기존 API에서는 시간대역(시차)를 처리하기 위해 로직들을 직접 구현해야 했지만, Local 과 zinedDate/Time API를 활용하면 손쉽게 처리 할 수 있다. - Calendar는 0월 부터 시작한다.
월(month)은 0부터 일(day of month)은 1부터 시작한다. 엄청 헷갈림.
LocalDateTime
LocalDateTime은 LocalDate 객체와 LocalTime 객체를 내부 변수(private final)로 가지고 있다.
이에 따라 LocalDateTime 의 생성함수는 LocalDate 객체와 LocalTime 의 생성 함수를 합쳐놓은 모양이고, 사용되는 함수들도 두 객체의 함수들과 유사하다.
생성방법
// 시스템 시간대역 기준 오늘
LocalDateTime.now();
// 현재 시스템 시간기준 오늘을 특정 지역(Timezone)의 시간으로 변환했을때의 날짜
// TimeZone 이름은 TZDB를 따르며(https://www.iana.org/time-zones) https://nodatime.org/TimeZones 참고
LocalDateTime.now(ZoneId.of("Asia/Seoul"));
LocalDateTime.now(ZoneId.of("America/New_York"));
// of 를 이용한 생성 함수
// of(int year, Month month, int dayOfMonth, int hour, int minute)
// of(int year, Month month, int dayOfMonth, int hour, int minute, int second)
// of(int year, Month month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond)
// of(int year, int month, int dayOfMonth, int hour, int minute)
// of(int year, int month, int dayOfMonth, int hour, int minute, int second)
// of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond)
// of(LocalDate date, LocalTime time)
// 2020년 1월 1일 15시 20분 35초, ISO 기준 날짜 패턴(yyyy-MM-ddT)을 입력 받음
LocalDateTime.parse("2020-01-0T15:20:35")
// 2020년 1월 1일 17시 23분 14초, 사용자 지정 날짜 패턴을 입력 받음)
LocalDateTime.parse("2020.01.01 17-23-14", DateTimeFormatter.ofPattern("yyyy.MM.dd HH-mm-ss"))
LocalDateTime 에는 날짜를 더하거나 빼는 편리한 기능도 존재 한다.
편리한 기능들
LocalDateTime localDateTime = LocalDateTime.now();
// 2023-09-19T00:18:00.621820200
// minus (시간 빼기)
// minus(TemporalAmount amount)
localDateTime.minus(Duration.ofDays(3)); // localDateTime에서 3일을 뺀다
// minus(long amountToSubtract, TemporalUnit unit)
localDateTime.minus(5, ChronoUnit.DAYS); // localDateTime에서 5일을 뺀다
localDateTime.minusDays(2); // localDateTime에서 2일을 뺀다
localDateTime.minusHours(2); // localDateTime에서 2시간 뺀다
localDateTime.minusXXXXXXX(2);
// plus (시간 더하기)
// plus(TemporalAmount amount)
localDateTime.plus(Duration.ofDays(3)); // localDateTime에서 3일을 더한다.
// plus(long amountToSubtract, TemporalUnit unit)
localDateTime.plus(5, ChronoUnit.DAYS); // localDateTime에서 5일을 더한다.
localDateTime.plusDays(2); // localDateTime에서 2일을 더한다.
localDateTime.plusHours(2); // localDateTime에서 2시간을 더한다.
localDateTime.plusXXXXXXX(2);
// with (시간 변경하기)
localDateTime.with(TemporalAdjusters.firstDayOfMonth()); // 날짜를 localDateTime 의 월의 첫번째 날로 변경한다.
localDateTime.with(ChronoField.HOUR_OF_DAY, 10); // 시간을 10시로 변경한다.
localDateTime.withYear(2020); // 년도를 2020년으로 변경한다.
ZonedDateTime
Timezone 이 적용된 날짜와 시간을 다루는 경우, ZonedDateTime을 사용하면 여러가지 편리한 점을 누릴 수 있다.
ZoneId 기반으로 객체를 생성하며, 대부분의 함수들이 LocalDateTime의 그것과 동일하다.
사용가능한 ZoneId 를 조회하는 방법은 아래와 같다.
사용 가능한 ZoneId 조회 하는 법
Set<String> allZoneIds = ZoneId.getAvailableZoneIds();
allZoneIds.forEach(System.out::println);
// 위 코드로 ZoneID를 확인하거나 https://nodatime.org/TimeZones 를 참고한다.
Period
Period는 서로 다른 두 날짜의 차이(년, 월, 일 단위)를 나타내는 클래스로, 쉽게 기간을 나타내는 클래스 라고 생각하면 된다.
생성하는 방법은 서로 다른 두 날을 인자로 생성하는 방법과 기간(년, 월, 일수)로 생성하는 방법이 있다.
// 2020년 1월 1일 ~ 2020년 1월 2일 사이 기간 (1일)
Period period = Period.between(LocalDate.of(2020, 1, 1), LocalDate.of(2020, 1, 2));
// 10일
Period period2 = Period.ofDays(10);
// 3달
Period period3 = Period.ofMonths(3);
Duration
Period와 유사하며 시간(Time) 단위를 포함하고 있다.
참고
https://www.baeldung.com/java-8-date-time-intro
https://www.geeksforgeeks.org/new-date-time-api-java8/?ref=lbp
https://www.geeksforgeeks.org/java-time-localdatetime-class-in-java/?ref=lbp
https://www.geeksforgeeks.org/java-time-zoneddatetime-class-in-java/?ref=lbp
'Java' 카테고리의 다른 글
(spring boot 3.1 이상) 간단한 설정(@ServiceConnection)으로 testcontainer 사용하기 (0) | 2023.10.16 |
---|---|
Java - Srping 시작할 때 동작하는 코드 작성하는 법 (0) | 2023.09.23 |
Java Record (레코드) (0) | 2023.09.10 |
Java Optional 사용법 (0) | 2023.09.03 |
Java 람다(Lambda) 표현식, Functional Interface 에 대한 조언 (0) | 2023.08.26 |