기존에 사용하던 날짜와 시간 Api 는 아래와같다.
Date date = new Date();
Calendar calendar = new Gregoriancalendar();
SimpleDateFormat dateFormat = new SimpleDateFormat();
Java8 에 새로운 날짜와 시간 API 가 생긴 이유
- 그 전까지 사용하던 java.util.Date 클래스는 mutable 하기 때문에 thread safe 하지 않다.
- .setTime( ) 시 변경이 가능하며, 멀티 쓰레드 환경에서 안전하게 쓰기 어렵다.
- 클래스 이름이 명확하지 않다. Date 인데 시간까지 다룬다.
- 버그 발생할 여지가 많다.
- 타입 안정성이 없고, 월이 0부터 시작한다거나 등
- 날짜 시간 처리가 복잡한 애플리케이션에서는 보통 Joda time 을 쓰곤 했다.
- Joda time? java8 이전에 자주 사용하던 시관 & 날짜 관련 라이브러리
주요 API
- 기계용 시간 (machine time) 과 인류용 시간 (human time)으로 나눌 수 있다.
- 기게용 시간은 EPOCK (1970년 1월 1일 0시 0분 0초)부터 현재까지의 타임스탬프를 표현한다.
- 인류용 시간은 우리가 흔히 사용하는 연, 월, 일, 시, 분, 초 등을 표현한다.
- 타임스탬프는 Instant를 사용한다.
- 특정 날짜(LocalDate), 시간(LocalTime), 일시(LocalDateTime)를 사용할 수 있다.
- 기간을 표현할 때는 Duration (시간 기반)과 Period (날짜 기반) 을 사용할 수 있다.
- DateTimeFormatter 를 사용해서 일시를 특정한 문자열로 포매팅할 수 있다.
실습
package com.study.java8to11;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class DateStudy {
public static void main(String[] args) {
// 1. [기계용 시간] 지금 이 순간을 기계 시간으로 표현하는 방법
// Universal Time Coordinated == Greenwich Mean Time
Instant instant = Instant.now();
System.out.println(instant); // 기준시 UTC, GMT
System.out.println(instant.atZone(ZoneId.of("UTC")));
ZoneId zone = ZoneId.systemDefault();
System.out.println(zone); // Asia/Seoul
ZonedDateTime zonedDateTime = instant.atZone(zone);
System.out.println(zonedDateTime); // 2022-05-05T17:52:39.218033+09:00[Asia/Seoul]
// 2. [인류용 시간]
LocalDateTime now = LocalDateTime.now();
System.out.println(now); // 2022-05-05T17:52:39.234404
LocalDateTime birthDay = LocalDateTime.of(1992, Month.APRIL, 19, 0, 0, 0);
System.out.println(birthDay);
// 특정 Zone 의 특정 일시를 리턴 [방법 1]
ZonedDateTime nowInKorea = ZonedDateTime.now(ZoneId.of("Asia/Seoul"));
System.out.println(nowInKorea);
// 특정 Zone 의 특정 일시를 리턴 [방법 2]
Instant nowInstant = Instant.now();
ZonedDateTime zonedDateTime2 = nowInstant.atZone(ZoneId.of("Asia/Seoul"));
System.out.println(zonedDateTime2);
// 3. 기간을 표현하는 방법
LocalDate today = LocalDate.now();
LocalDate thisYearBirthday = LocalDate.of(2022, Month.JULY, 15);
// 일 수 차이 확인 [방법 1]
Period period = Period.between(today, thisYearBirthday);
System.out.println(period.getDays());
// 일 수 차이 확인 [방법 2]
Period until = today.until(thisYearBirthday);
System.out.println(until.get(ChronoUnit.DAYS));
// Period 는 인류용 시간 비교, Duration 은 기계용 시간비교
Instant now2 = Instant.now();
Instant plus = now2.plus(10, ChronoUnit.SECONDS);
Duration between = Duration.between(now2, plus);
System.out.println(between.getSeconds());
// 4. 파싱 또는 포매팅
// 포매팅
LocalDateTime now3 = LocalDateTime.now();
DateTimeFormatter MMddyyyy = DateTimeFormatter.ofPattern("MM/dd/yyyy");
System.out.println(now3.format(MMddyyyy));
// 파싱
LocalDate parse = LocalDate.parse("04/19/1992", MMddyyyy);
System.out.println(parse);
// 5. 레거시 API 지원
// GregorianCalendar와 Date 타입의 인스턴스를 Instant나 ZonedDateTime으로 변환 가능.
// java.util.TimeZone에서 java.time.ZoneId로 상호 변환 가능.
Date date = new Date();
Instant instant2 = date.toInstant();
Date nowDate = Date.from(instant2);
GregorianCalendar gregorianCalendar = new GregorianCalendar();
ZonedDateTime dateTime = gregorianCalendar.toInstant().atZone(ZoneId.systemDefault());
GregorianCalendar from = GregorianCalendar.from(dateTime);
ZoneId newZoneAPI = TimeZone.getTimeZone("PST").toZoneId();
TimeZone legacyZoneAPI = TimeZone.getTimeZone(newZoneAPI);
Instant newInstant = new Date().toInstant();
Date legacyInstant = Date.from(newInstant);
}
}
참고
- 백기선 - 더 자바, Java8
- https://codeblog.jonskeet.uk/2017/04/23/all-about-java-util-date/
- https://docs.oracle.com/javase/tutorial/datetime/overview/index.html
- https://docs.oracle.com/javase/tutorial/datetime/iso/overview.html
- https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#pre
'프로그래밍 > Java' 카테고리의 다른 글
CompletableFuture (2) - Excutors (0) | 2022.05.06 |
---|---|
CompletableFuture (1) - 자바 Concurrent 프로그래밍 소개 (0) | 2022.05.06 |
Optional (0) | 2022.05.05 |
Stream (0) | 2022.05.04 |
Lombok 동작원리 (0) | 2022.05.03 |