JDK 1.0에서는 Date 클래스를 사용하여 날짜에 관한 처리를 수행했지만 Date 클래스는 직관적이지 않고 기능이 부족하여 현재는 사용하지 않는다
JDK 1.1부터 새롭게 제공된 Calendar 클래스는 날짜와 시간에 대한 정보를 손쉽게 얻을 수 있지만 아래와 같은 문제점이 있다
- Calendar 인스턴스는 불변 객체(immutable object)가 아니라서 값이 수정될 수 있다
- 윤초(leap second)와 같은 특별한 상황을 고려하지 않는다
- Calendar 클래스에서는 월을 나타낼 때 1월부터 12월을 0부터 11까지로 표현한다
이 때문에 많은 자바 개발자들은 Calendar 클래스뿐만 아니라 더 나은 성능의 Joda-Time이라는 라이브러리를 함께 사용해 왔다
Java SE 8부터 제공되는 java.time 패키지에는 자바에서 날짜와 시간을 다루는 데 사용되는 필수 클래스들이 포함되어 있음
위와 같은 문제점을 모두 해결하며, 다양한 기능을 지원하는 다수의 하위 패키지를 포함하고 있음
하위 패키지 종류
1. java.time.chrono : ISO-8601에 정의된 표준 달력 이외의 달력 시스템을 사용할 때 필요한 클래스들
2. java.time.format : 날짜와 시간에 대한 데이터를 구문분석하고 형식화하는 데 사용되는 클래스들
3. java.time.temporal : 날짜와 시간에 대한 데이터를 연산하는 데 사용되는 보조 클래스들<br?
4. java.time.zone : 타임 존(time-zone)과 관련된 클래스들
java.time 패키지에 속하는 모든 클래스의 인스턴스는 불변 객체로 생성되기 때문에 위의 메소드들은 모두 새로운 객체를 생성하여 반환한다
- LocalDate 클래스는 날짜를 표현할 때 사용한다
- LocalTime 클래스는 시간을 표현할 때 사용한다
- LocalDateTime 클래스는 날짜와 시간을 한 번에 표현하고 싶을 때 사용한다
- ZonedDateTime 클래스는 특정 타임 존(time-zone)에 해당하는 날짜와 시간을 다루는 데 사용한다
- Instant 클래스는 특정 시점의 날짜와 시간을 나노초(nanosecond) 단위로 표현하는 타임스탬프(time-stamp)를 다루는 데 사용된다
- Period 클래스는 두 날짜 사이의 차이를 표현하는 데 사용된다
- Duration 클래스는 두 시각 사이의 차이를 표현하는 데 사용된다
LocalDate 클래스는 날짜를 표현하는 데 사용되며, LocalTime 클래스는 시간을 표현하는 데 사용된다
java.time 패키지에 포함된 대부분의 클래스들은 이 두 클래스를 확장한 것이 많음
LocalDate와 LocalTime 클래스는 객체를 생성하기 위해서 now()와 of() 메소드가 클래스 메소드를 제공된다
now(): 현재의 날짜와 시간을 이용하여 새로운 객체를 생성하여 반환
of(): 전달된 인수를 가지고 특정 날짜와 시간을 표현하는 새로운 객체를 생성하여 반환
LocalDate today = LocalDate.now();
LocalTime present = LocalTime.now();
System.out.println(today + " " + present);
// static LocalDate of(int year, int month, int dayOfMonth)
LocalDate birthDay = LocalDate.of(1982, 02, 19);
// static LocalTime of(int hour, int minute, int second, int nanoOfSecond)
LocalTime birthTime = LocalTime.of(02, 02, 00, 100000000);
System.out.println(birthDay + " " + birthTime);
2017-02-16 09:21:50.634
1982-02-19 02:02:00.100
LocalDate와 LocalTime 클래스는 특정 필드의 값을 가져오기 위해서 다양한 getter 메소드를 제공한다
java.time 패키지에서는 1월을 1로 표현하여 월의 범위가 1~12가 되었으며, 요일은 월요일부터 1로 표현하도록 변경되었다
LocalDate today = LocalDate.now();
System.out.println("올해는 " + today.getYear() + "년입니다.");
System.out.println("이번달은 " + today.getMonthValue() + "월입니다.");
System.out.println("오늘은 " + today.getDayOfWeek() + "입니다.");
System.out.println("오늘은 1년 중 " +
today.get(ChronoField.DAY_OF_YEAR) + "일째 날입니다.");
올해는 2017년입니다.
이번달은 2월입니다.
오늘은 THURSDAY입니다.
오늘은 1년 중 47일째 날입니다.
LocalTime present = LocalTime.now();
System.out.println("현재 시각은 " + present.getHour() +
"시 " + present.getMinute() + "분입니다.");
현재 시간은 9시 22분입니다.
월과 시와 같이 날짜와 시간과 관련된 필드를 정의해 놓은 인터페이스
이 인터페이스를 구현하여 날짜와 시간을 나타낼 때 사용하는 열거체가 바로 ChronoField
java.time 패키지를 구성하는 클래스의 메소드에서는 이 열거체를 이용하여 날짜와 시간을 처리하고 있다
ChronoField 열거체에 정의된 대표적인 열거체 상수는 아래와 같다
ERA: 시대
YEAR: 연도
MONTH_OF_YEAR: 월
DAY_OF_MONTH: 일
DAY_OF_WEEK: 요일 (월요일:1, 화요일:2, ..., 일요일:7)
AMPM_OF_DAY: 오전/오후 (오전:0, 오후 1)
HOUR_OF_DAY: 시(0~23)
CLOCK_HOUR_OF_DAY: 시(1~24)
HOUR_OF_AMPM: 시(0~11)
CLOCK_HOUR_OF_AMPM: 시(1~12)
MINUTE_OF_HOUR: 분
SECOND_OF_MINUTE: 초
DAY_OF_YEAR: 해당 연도의 몇 번째 날 (1~365, 윤년이면 366)
EPOCH_DAY: EPOCH(1970년 1월 1일)을 기준으로 몇 번째 날
LocalTime present = LocalTime.now();
String ampm;
if(present.get(ChronoField.AMPM_OF_DAY) == 0) {
ampm = "오전";
} else {
ampm = "오후";
}
System.out.println("지금은 " + ampm + " " + present.get(ChronoField.HOUR_OF_AMPM) + "시입니다.");
지금은 오전 9시입니다.
LocalDate와 LocalTime 클래스는 날짜와 시간 객체에 접근하여 특정 필드의 값을 변경하기 위해서 with() 메소드를 사용한다
LocalDate with(TemporalField field, long newValue)
해당 날짜 객체에서 특정 필드를 전달된 새로운 값으로 설정한 새로운 날짜 객체를 반환함
LocalDate withYear(int year)
해당 날짜 객체에서 연도(YEAR) 필드를 전달된 새로운 값으로 설정한 새로운 날짜 객체를 반환함
LocalDate withMonth(int month)
해당 날짜 객체에서 월(MONTH_OF_YEAR) 필드를 전달된 새로운 값으로 설정한 새로운 날짜 객체를 반환함
LocalDate withDayOfMonth(int dayOfMonth)
해당 날짜 객체에서 일(DAY_OF_MONTH) 필드를 전달된 새로운 값으로 설정한 새로운 날짜 객체를 반환함
LocalDate withDayOfYear(int dayOfYear)
해당 날짜 객체에서 DAY_OF_YEAR 필드를 전달된 새로운 값으로 설정한 새로운 날짜 객체를 반환함.
withYear 사용 예시
LocalDate today = LocalDate.now();
System.out.println("올해는 " + today.getYear() + "년입니다.");
LocalDate otherDay = today.withYear(1982);
System.out.println("올해는 " + otherDay.getYear() + "년입니다.");
올해는 2017년입니다.
올해는 1982년입니다.
withDayOfYear 사용 예시
LocalDate date = LocalDate.of(2023, 10, 16);
System.out.println("Original date: " + date);
LocalDate modifiedDate = date.withDayOfYear(100); // 연도의 100번째 날로 변경
System.out.println("Modified date: " + modifiedDate);
Original date: 2023-10-16
Modified date: 2023-04-10
with 사용 예시
LocalDate date = LocalDate.of(2023, 10, 16);
System.out.println("Original date: " + date);
LocalDate modifiedMonth = date.with(ChronoField.MONTH_OF_YEAR, 2); // 2월로 변경
System.out.println("Month modified: " + modifiedMonth);
LocalDate modifiedDay = date.with(ChronoField.DAY_OF_MONTH, 25); // 25일로 변경
System.out.println("Day modified: " + modifiedDay);
Original date: 2023-10-16
Month modified: 2023-02-16
Day modified: 2023-10-25
LocalTime with(TemporalField field, long newValue)
해당 시간 객체에서 특정 필드를 전달된 새로운 값으로 설정한 새로운 시간 객체를 반환함
LocalTime withHour(int hour)
해당 시간 객체에서 시(HOUR_OF_DAY) 필드를 전달된 새로운 값으로 설정한 새로운 시간 객체를 반환함
LocalTime withMinute(int minute)
해당 시간 객체에서 분(MINUTE_OF_HOUR) 필드를 전달된 새로운 값으로 설정한 새로운 시간 객체를 반환함
LocalTime withSecond(int second)
해당 시간 객체에서 초(SECOND_OF_MINUTE) 필드를 전달된 새로운 값으로 설정한 새로운 시간 객체를 반환함
LocalTime withNano(int nanoOfSecond)
해당 시간 객체에서 나노초(NANO_OF_SECOND) 필드를 전달된 새로운 값으로 설정한 새로운 시간 객체를 반환함
LocalTime present = LocalTime.now();
System.out.println("현재 시각은 " + present.getHour() + "시입니다.");
LocalTime otherTime = present.withHour(8);
System.out.println("현재 시각은 " + otherTime.getHour() + "시입니다.");
현재 시간은 9시입니다.
현재 시간은 8시입니다.
with() 메소드 이외에도 특정 필드의 값을 더하거나 뺄 수 있는 다양한 plus()와 minus() 메소드도 제공한다
LocalTime present = LocalTime.now();
System.out.println("현재 시각은 " + present.get(ChronoField.HOUR_OF_DAY) + "시입니다.");
LocalTime otherTime = present.plus(2, ChronoUnit.HOURS);
System.out.println("바뀐 시간은 " + otherTime.getHour() + "시입니다.");
LocalTime anotherTime = present.minus(6, ChronoUnit.HOURS);
System.out.println("바뀐 시간은 " + anotherTime.getHour() + "시입니다.");
```java
현재 시간은 9시입니다.
바뀐 시간은 11시입니다.
바뀐 시간은 3시입니다.
ChronoUnit은 날짜와 시간의 기간을 나타내기 위한 다양한 시간 단위를 제공한다
ChronoField는 날짜와 시간의 구체적인 필드를 나타낸다
LocalDate와 LocalTime 클래스에도 객체를 비교할 수 있는 compareTo() 메소드가 오버라이딩되어 있다
하지만 더욱 편리하게 날짜와 시간 객체를 서로 비교할 수 있도록 다음과 같은 메소드를 제공한다
- isEqual() 메소드 : equals() 메소드와는 달리 오직 날짜만을 비교함.
(LocalDate 클래스에서만 제공)
- isBefore() 메소드 : 두 개의 날짜와 시간 객체를 비교하여 현재 객체가 명시된 객체보다 앞선 시간인지를 비교함.
- isAfter() 메소드 : 두 개의 날짜와 시간 객체를 비교하여 현재 객체가 명시된 객체보다 늦은 시간인지를 비교함.
LocalDate today = LocalDate.now();
LocalDate otherDay = LocalDate.of(1982, 02, 19);
System.out.println(today.compareTo(otherDay));
System.out.println(today.isBefore(otherDay));
System.out.println(today.isEqual(otherDay));
35
false
false