원래 날짜를 다루기 위해 사용했던, Date와 Calender가 가지고 있던 단점을 해소하기 위해서 드디어 JDK1.8부터 'java.time패키지'가 추가되었다.
패키지 | 설명 |
---|---|
java.time | 날짜와 시간을 다루는데 필요한 핵심 클래스들을 제공 |
java.time.chrono | 표준(ISO)이 아닌 달력 시스템을 위한 클래스들을 제공 |
java.time.format | 날짜와 시간을 파싱하고, 형식화하기 위한 클래스들을 제공 |
java.time.temporal | 날짜와 시간의 필드(field)와 단위(unit)를 위한 클래스들을 제공 |
java.time.zone | 시간대(time-zone)와 관련된 클래스들을 제공 |
java.time패키지는 잘짜와 시간을 별도의 클래스로 분리해 놓았다. 시간을 표현할 때는 LocalTime, 날짜를 표현할 때는 LocalDate클래스를 사용한다. 날짜와 시간이 모두 필요할 때는 LocalDateTime클래스를 사용하면 된다.
LocalDate + LocalTime → LocalDateTime
여기서 시간대(time-zone)까지 다뤄야 한다면, ZonedDateTime 클래스 사용
LocalDateTime + 시간대 → ZonedDateTime
※ Date와 유사한 클래스로 Instant가 있는데, 이클래스는 날짜와 시간을 초 단위(정확히는 나노초)로 표현한다.
Period와 Duration
날짜와 시간의 간격을 표현하기 위한 클래스
객체생성 - now(), of()
LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime dateTime = LocalDateTime.now();
ZonedDateTime dateTimeInKr = ZonedDateTime.now();
Localdate date = LocalDate.of(2015, 11, 23); // 2015년 11월 23일
LocalTime time = LocalTime.of(23, 59, 59); // 23시 59분 59초
LocalDateTime dateTime = LocalDateTime.of(date, time);
ZonedDateTime zDateTime = ZonedDateTime.of(dateTime, Zoned.of("Asia/Seoul"));
LocalDate와 LocalTime은 java.time패키지의 가장 기본이 되는 클래스이며 나머지 클래스들은 이들의 확장이다
with() : 날짜와 시간에서 특정 필드값을 변경
필드 변경 메서드들은 항상 새로운 객체를 생성해서 반환하므로 대입 연산자를 같이 사용해야 한다.
date = date.withYear(2000); //년도를 2000년으로 변경
time = time.withHour(12); //시간을 12시로 변경
plus(), minus() : 날짜와 시간에서 특정 필드에 값을 더하거나 뺌
※plus()메서드만 적음
날짜와 시간의 비교 - isAfter(), isBefor(), isEqual()
단순 비교
int result = date1.compareTo(date2); // 같으면 0, date1이 이전이면 -1, 이후면 1을 반환.
연표가 다른 두 날짜 비교
LocalDate kDate = Localdate.of(1999, 12, 31);
JapaneseDate jDate = JapaneseDate.of(1999, 12, 31);
System.out.println(kDate.equals(jDate)); // falus YEAR_OF_ERA가 다름
System.out.println(kDate.isEqual(jDate)); // true
날짜 - 날짜 = Period
시간 - 시간 = Duration
between()
두 날짜 date1과 date2의 차이를 구할때 between()메서드 사용
LocalDate date1 = LocalDate.of(2014, 1, 1);
LocalDate date2 = LocalDate.of(2015, 12, 31);
Period pe = Period.between(date1, date2);
date1이 date2보다 날짜 상으로 이전이면 양수로, 이후면 음수로 Period에 저장.
시간차이를 구할때는 Duration을 사용한다는 것을 제외하고 Period와 똑같다.
Period, Duration에서 특정 필드 값을 얻을 때는 get()을 사용
형식화(formatting)와 관련된 클래스들은 java.time.format패키지에 들어있는데, 이 중에서 DateTimeFormatter가 핵심이다. 이 클래스에는 자주 쓰이는 다양한 형식들을 기본적으로 정의하고 있으며, 그 외의 형식이 필요하다면 직접 정의해서 사용할 수도 있다.
LocalDate date = LocalDate.of(2016, 1, 2);
String yyyymmdd = DateTimeFormatter.ISO_LOCAL_DATE.format(date); // "2016-01-02"
String yyyymmdd = date.format(DateTimeFormatter.ISO_LOCAL_DATE); // "2016-01-02"
날짜와 시간의 형식화는 위와 같이 format()이 사용되는데, 이 메서드는 DateTimeFormatter뿐만 아니라 LocalDate나 LocalTime같은 클래스에도 있다. 같은 기능을 하니 상황에 따라 편한 쪽을 선택해서 사용.
아래의 표는 DateTimeFormatter에 상수로 정의된 형식들의 목록이다.
로케일에 종속된 형식화
DateTimeFormatter의 static메서드 ofLocalizedDate(), ofLocalizedTime(), ofLocalizedDateTime()은 로케일에 종속적인 포맷터를 생성한다.
DateTimeFormatter formatter =
DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
String shortFormat = formatter.format(LocalDate.now());
FormatStyle의 종류에 따른 출력형태
FormatStyle | 날짜 | 시간 |
---|---|---|
FULL | 2000년 1월 1일 토요일 | N/A |
LONG | 2000년 1월 1일 (토) | 오후 9시 15분 13초 |
MIDIUM | 2000. 1. 1 | 오후 9:15:13 |
SHORT | 00. 1. 1 | 오후 9:15 |
출력형식 직접 정의하기
DateTimeFormatter의 ofPattern()으로 원하는 출력형식을 직접 작성할 수 있다.
ZonedDateTime zdateTime = ZonedDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
System.out.println(zdateTime.format(formatter));
출력되는 형식에 사용되는 기호의 목록
// 기본적인 파싱
LocalDate newDate = LocalDate.parse("2001-01-01");
LocalTime newTime = LocalTime.parse("23:59:59");
LocalDateTime newDateTime = LocalDateTime.parse("2001-01-01T23:59:59");
// ofPattern()을 이용한 파싱
DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime endOfYear = LocalDateTime.parse("2015-12-31 23:59:59", pattern);