[Java] 새로운 날짜/시간 API Time소개, Date의 단점
Goal
- Time API가 생긴 배경(이유)
- 주요 API 설명
자바 8에서 새로운 날짜와 시간 API가 생긴 이유
- 그전까지 사용하던 java.util.Date클래스는 mutable하기 때문에 thread safe하지 않습니다.
- 클래스 이름이 명확하지 않다. Date인데 시간까지 다룹니다.
- 버그 발생할 여지가 많다 (타입 안전성이 없고, 월이 0부터 시작한거나)
예제를 위한 코드
public static void main(String[] args) throws InterruptedException {
Date date = new Date(); // 이름은 데이트인데 시간까지 다룬다
long time = date.getTime();
System.out.println(time); // 기계 시간 출력됨
// mutable 예제
Thread.sleep(1000 * 3);
Date after3Seconds = new Date();
System.out.println("after3Seconds = " + after3Seconds); // 3초 이후 시간
after3Seconds.setTime(time);
System.out.println("after3Seconds = " + after3Seconds); // 3초 이전 시간으로 변경
// mutable객체는 멀티쓰레드 환경에서 안전하게 사용하기 어렵다.
// Thread1이 Date를 사용중에 Thread2가 끼어들어서 값을 바꿀 수도 있다.
// 버그가 발생할 수 있다.
GregorianCalendar calendar = new GregorianCalendar(2000, 7, 15);
// 숫자로 사용할 경우 조심 month 조심 0부터 시작함 실수할 여지가 많음 (type safe하지 않음)
}
주요 API
- 기계용 시간 (machine time)과 인류용 시간(human time)으로 나눌 수 있습니다.
- 기계용 시간은 EPOCK (1970년 1월 1일 0시 0분 0초)부터 현재까지의 타임스탬프를 표현합니다.
- 인류용 시간은 우리가 흔히 사용하는 연,월,일,시,분,초 등을 표현합니다.
- 타임스탬프는 Instant를 사용합니다.
- 특정 날짜(LocalDate), 시간(LocalTime), 일시(LocalDateTime)를 사용할 수 있습니다.
- 기간을 표현할 때는 Duration (시간 기반)과 Period (날짜 기반)를 사용할 수 있습니다.
- DateTimeFormatter를 사용해서 일시를 특정한 문자열로 포매팅할 수 있습니다.
현재 시간을 기계 시간으로 표현
- Instant.now(); 현재 UTC (GMT)를 리턴합니다.
Instant instant = Instant.now();
System.out.println("instant = " + instant); // GMT , UTC 시간
ZoneId zone = ZoneId.systemDefault(); // 시스템 기준 시점
System.out.println("zone = " + zone);
ZonedDateTime zonedDateTime = instant.atZone(zone); // 시스템 기준 시점 시간
System.out.println("zonedDateTime = " + zonedDateTime);
인류용 일시를 표현하는 방법
LocalDateTime now = LocalDateTime.now(); // 현재 시스템 Zone에 해당하는 일시를 리턴한다
LocalDateTime past =
LocalDateTime.of(1999, Month.APRIL, 15, 0, 0, 0);
// 로컬의 특정 일시
ZonedDateTime seoul = ZonedDateTime.now(ZoneId.of("Asia/Seoul")); // 특정 Zone의 특정 일시를 리턴
기간을 표현하는 방법
- Period / Duration . beteen()
LocalDate today = LocalDate.now();
LocalDate christmas = LocalDate.of(2020, Month.DECEMBER, 25);
Period between = Period.between(today, christmas); // *주의* 년 월 일로 반환합니다.
System.out.println(between.getMonths());
System.out.println(between.getDays());
System.out.println(between.get(ChronoUnit.DAYS)); // 위랑 똑같음
long betweenDays = ChronoUnit.DAYS.between(today, christmas); // 오직 일수만 계산해서 반환합니다.
System.out.println("between = " + betweenDays);
포매팅
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yy");
System.out.println(now.format(formatter));
읽어주셔서 감사합니다.
피드백, 문의 댓글로 남겨주시면 감사하겠습니다.
References
www.inflearn.com/course/the-java-java8/dashboard
docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#predefined
'Java' 카테고리의 다른 글
Generic Type Erasure는 어떻게 타입캐스팅을 하는건가요? (0) | 2021.12.07 |
---|---|
Java Parallel Programming 성능 테스트 및 고려사항 (JMH) (2) | 2021.07.25 |
HashMap은 어떻게 동작할까? + 자바8에서의 변화 (0) | 2021.06.20 |
[Java] 함수형 인터페이스, 람다식 (0) | 2021.02.09 |