✍️ 자바 8에 새로운 시간 API가 생긴 이유
자바8 이전에 사용했던 시간 관련 클래스 Date, Calendar가 여러모로 불편함을 유발했다.
public static void main(String[] args) {
Date date = new Date();
Calendar calendar = new GregorianCalendar();
}
첫째로, 작명이 제대로 되어있지 않다. 클래스의 이름이 Date임에도 시간(Time)까지도 나타낼 수 있고 Time 스탬프도 찍을 수 있다.
Date date = new Date();
long time = date.getTime(); // Date(날짜)에서 time(시간)을 가져온다고?
심지어 getTime으로 가져오는 값이 현재의 시간이 아닌 1970.1.1로부터의 milliseconds를 반환한다.
/**
* Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
* represented by this {@code Date} object.
*
* @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
* represented by this date.
*/
public long getTime() {
return getTimeImpl();
}
둘째로, Date 객체가 mutable 하다. 때문에
메인 쓰레드를 3초 동안 재우고 다시 시간을 찍어보면 3초가 지난 시간이 찍힌다.
public static void main(String[] args) throws InterruptedException {
Date date = new Date();
long time = date.getTime();
System.out.println(date);
Thread.sleep(1000 * 3); // 3초 슬립
Date after3Seconds = new Date();
System.out.println(after3Seconds);
}
// Tue Feb 22 21:35:13 KST 2022
// Tue Feb 22 21:35:16 KST 2022
여기까지는 좋으나, setTime을 사용하면 객체의 시간 값을 변경할 수 있다.
public static void main(String[] args) throws InterruptedException {
Date date = new Date();
long time = date.getTime();
System.out.println(date);
Thread.sleep(1000 * 3); // 3초 슬립
Date after3Seconds = new Date();
System.out.println(after3Seconds);
after3Seconds.setTime(time);
System.out.println(after3Seconds);
}
// Tue Feb 22 21:38:16 KST 2022
// Tue Feb 22 21:38:19 KST 2022
// Tue Feb 22 21:38:16 KST 2022
이처럼 상태를 변경할 수 있는 객체를 mutable 객체
반대로 상태를 변경할 수 없는 객체를 immutable 객체라고 한다.
mutable 객체는 멀티 스레드 환경에서 안전하게 사용하기 어렵다.
셋째로, Type safety 하지 못해 버그가 발생할 확률이 높다.
2022년 12월 25일을 그레고리안 캘린더로 인스턴스화하면 아래 코드일 것 같으나 이는 잘못된 코드이다.
public static void main(String[] args) throws InterruptedException {
Calendar christmas2022 = new GregorianCalendar(2022, 12, 25);
}
월에 해당하는 month가 문제가 된다. 주석을 읽어보면 Month value is 0-based. e.g., 0 for January. Month의 베이스 값은 0이다. 즉 1월은 0에 매치된다.
/**
* Constructs a {@code GregorianCalendar} with the given date set
* in the default time zone with the default locale.
*
* @param year the value used to set the {@code YEAR} calendar field in the calendar.
* @param month the value used to set the {@code MONTH} calendar field in the calendar.
* Month value is 0-based. e.g., 0 for January.
* @param dayOfMonth the value used to set the {@code DAY_OF_MONTH} calendar field in the calendar.
*/
public GregorianCalendar(int year, int month, int dayOfMonth) {
this(year, month, dayOfMonth, 0, 0, 0, 0);
}
🍊 Date, Time 주요 API
- 자바 8부턴 기계용 시간(machine time)과 인류용 시간(human time)으로 나눌 수 있다.
- 기계용 시간은 EPOCK (1970년 1월 1일 0시 0분 0초)부터 현재까지의 타임스탬프를 표현한다.
- 인류용 시간은 우리가 흔히 사용하는 연, 월, 일, 시, 분, 초 등을 표현한다.
- 타임스탬프는 Instant를 사용한다.
- 특정 날짜(LocalDate), 시간(LocalTime), 일시(LocalDateTime)를 사용할 수 있다.
- 기간을 표현할 땐 Duration(시간 단위)과 Period(날짜 단위)를 사용할 수 있다.
- DateTimeFormatter를 사용해서 시간을 특정한 문자열로 포맷팅할 수 있다.
'Java > Java 8' 카테고리의 다른 글
[Java8] Chapter 6-1. Java Concurrent 프로그래밍 (0) | 2022.03.01 |
---|---|
[Java8] Chapter 5-2. Date와 Time 실습 (2) (0) | 2022.02.23 |
[Java8] Chapter 4-2. Optional API 실습 (2) (0) | 2022.02.21 |
[Java8] Chapter 4-1. Optional (1) (0) | 2022.02.20 |
[Java8] Chapter 3-2. Stream API 실습 (2) (0) | 2022.02.20 |