[Java-10] 날짜와 시간 & 형식화 - java.time패키지
1. java.time패키지란?
- JDK1.8부터 추가된 패키지
- Date와 Calendar의 단점을 해소
- Calendar클래스와 다르게 '불변(immutable)'임
- java.time패키지와 서브 패키지들
패키지 | 설 명 |
java.time | 날짜와 시간을 다루는데 필요한 핵심 클래스들을 제공 |
java.time.chrono | 표준(ISO)이 아닌 달력 시스템을 위한 클래스들을 제공 |
java.time.format | 날짜와 시간을 파싱하고, 형식화하기 위한 클래스들을 제공 |
java.time.temporal | 날짜와 시간의 필드(field)와 단위(unit)를 위한 클래스들을 제공 |
java.time.zone | 시간대(time-zone)와 관련된 클래스들을 제공 |
- Calendar클래스와 달리, java.time패키지에서는 날짜와 시간을 별도의 클래스로 분리
- 시간대(time-zone)까지 다룰 수 있음
- 객체 생성하기 : now(), of()
LocalDate date = LocalDate.now(); // 2015-11-23
LocalTime time = LocalTime.now(); // 21:53:01.875
LocalDateTime dateTime = LocalDateTime.now(); // 2015-11-23T21:53:01.875
ZonedDateTime dateTimeInKr = ZonedDateTime.now();
// 2015-11-23T21:53:01.875+09:00[Asia/Seoul]
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, ZoneId.of("Asia/Seoul"));
2. LocalDate와 LocalTime
1) 객체 생성 of(), now()
- of()는 여러 가지 버전이 제공됨
static LocalDate of(int year, Month month, int dayOfMonth)
static LocalDate of(int year, int month, int dayOfMonth)
static LocalTime of(int hour, int min)
static LocalTime of(int hour, int min, int sec)
static LocalTime of(int hour, int min, int sec, int nanoOfSecond)
- 일 단위나 초 단위로도 지정 가능
LocalDate date = LocalDate.ofYearDay(1998, 15); // 1998년 1월 15일
LocalTime time = LocalTime.ofSecondDay(86399); // 23시 59분 59초
2) 특정 필드의 값 가져오기 get(), getXXX()
클래스 | 메서드 | 설명 (1999-12-31 23:59:59) | |
LocalDate | int | getYear() | 년도(1999) |
int | getMonthValue() | 월(12) | |
Month | getMonth() | 월(DECEMBER) | |
int | getDayOfMonth() | 일(31) | |
int | getDayOfYear() | 같은 해의 1월 1일부터 몇번째 일(365) | |
DayOfWeek | getDayOfWeek() | 요일(FRIDAY) | |
int | lengthOfWeek() | 같은 달의 총 일수(31) | |
int | lengthOfYear() | 같은 해의 총 일수(365), 윤년이면 366 | |
boolean | isLeapYear() | 윤년여부 확인(false) | |
LocalTime | int | getHour() | 시(23) |
int | getMinute() | 분(49) | |
int | getSecond() | 초(59) | |
int | getNano() | 나노초(0) |
- Calendar와 달리 월(month)는 1~12, 요일은 월요일이 1, 화요일이 2, ... , 일요일이 7
3) 필드의 값 변경하기 with(), plus(), minus()
- with() : 원하는 필드 값 직접 변경
LocalDate withYear(int year)
LocalDate withMonth(int month)
LocalDate withDayOfMonth(int dayOfMonth)
LocalDate withDayOfYear(int dayOfYear)
LocalTime withHour(int hour)
LocalTime withMinute(int minut)
LocalTime withSecond(int second)
LocalTime withNano(int nanoOfSecond)
- plus(), minus() : 특정 필드에 값을 더하거나 뺌
LocalTime plus(TemporalAmount amountToAdd)
LocalTime plus(long amountToAdd, TemporalUnit unit)
LocalDate plus(TemporalAmount amountToAdd)
LocalDate plus(long amountToAdd, TemporalUnit unit)
4) 날짜와 시간의 비교 isAfter(), isBefore(), isEqual()
- compareTo()가 오버라이딩되어 있기 때문에 사용 가능하지만, 더 편리한 메서드들이 제공됨
boolean isAfter(ChronoLocalDate other)
boolean isBefore(ChronoLocalDate other)
boolean isEqual(ChronoLocalDate other) // LocalDate에만 있음
3. LocalDateTime, ZonedDateTime
1) LocalDate, LocalTime -> LocalDateTime
LocalDate date = LocalDate.of(2015, 12, 31);
LocalTime time = LocalTime.of(12, 34, 56);
// LocalDateTime 만들기
LocalDateTime dt = LocalDateTime.of(date, time);
LocalDateTime dt2 = date.atTime(time);
LocalDateTime dt3 = time.atDate(date);
LocalDateTime dt4 = date.atTime(12, 34, 56);
LocalDateTime dt5 = time.atDate(LocalDate.of(2015, 12, 31));
LocalDateTime dt6 = date.atStartOfDay();
2) LocalDateTime -> LocalDate, LocalTime
LocalDateTime dt = LocalDateTime.of(2015, 12, 31, 12, 34, 56);
LocalDate date = dt.toLocalDate();
LocalTime time = dt.toLocalTime();
3) LocalDateTime -> ZonedDateTime
ZoneId zid = ZoneId.of("Asia/Seoul");
ZonedDateTime zdt = dateTime.atZone(zid);
4) ZonedDateTime -> 날짜, 시간과 관련된 클래스
- toLocalDate(), toLocalTime(), toLocalDateTime(), toOffsetDateTIme(), toEpochSecond(), toInstant()
4. Period, Duration
1) 정의
- Peroid는 날짜의 차이, Duration은 시간의 차이를 계산하기 위한 것
날짜 - 날짜 = Period
시간 - 시간 = Duration
2) 차이 구하기 between()
LocalDate date1 = LocalDate.of(2014, 1, 1);
LocalDate date2 = LocalDate.of(2015, 12, 31);
Period pe = Period.between(date1, date2);
- date1이 date2보다 날짜 상으로 이전이면 양수, 이후면 음수로 Period에 저장
LocalTime time1 = LocalTime.of(00,00,00);
LocalTime time2 = LocalTime.of(12,34, 56);
Duration du = Duration.between(time1, time2);
3) 특정 필드의 값 가져오기 get()
long year = pe.get(ChronoUnit.YEARS);
long month = pe.get(ChronoUnit.MONTHS);
long day = pe.get(ChronoUnit.DAYS);
long sec = du.get(ChronoUnit.SECONDS);
long nano = du.get(ChronoUnit.NANOS);
- 단, Duration에는 getHours(), getMinute()이 없기 때문에, 직접 계산하거나 LocalTime으로 변환하여 얻어내야 함
4) 차이 구하기 until()
// Period pe = Period.between(today, birthDay);
Peroid pe = today.until(birthDay);
long dday = today.until(birthDay, ChronoUnit.DAYS);
- between()과 같은 기능을 수행하지만, between()은 static메서드이고 until()은 인스턴스 메서드임
5) 객체 생성 of(), with()
- LocalDate와 LocalTime에서의 사용법과 같음
- Period : of(), ofYears(), ofMonths(), ofWeeks(), ofDays()
- Duration : of(), ofDays(), ofHours(), ofMinutes(), ofSeconds() 등
6) 기타 메서드
- plusXXX(), minusXXX(), multipliedBy(), dividedBy() 등 사칙연산 메서드 제공
- 단, Peroid는 나눗셈을 위한 메서드가 없음
- isNegative() : 음수인지 확인
- isZero() : 0인지 확인
- negate(), abs() : 부호를 반대로 변경 (단, Period는 abs()가 없음)
7) 다른 단위로 변환 toXXX()
- toTotalMonths(), toDays(), toHours(), toMinutes() 등 존재
5. 파싱과 포맷
- 형식화(formatting)과 관련된 클래스들은 java.time.format패키지에 존재
1) 로케일(locale)에 종속된 형식화
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
String shortFormat = formatter.format(LocalDate.now());
- ofLocalizedDate(), ofLocalizedTime(), ofLocalizedDateTime()은 로케일(locale)에 종속적인 포멧터를 생성
2) 출력형식 직접 정의
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
- ofPattern()으로 원하는 출력형식 직접 작성 가능
3) 문자열을 날짜와 시간으로 파싱
static LocalDateTime parse(CharSequence text)
static LocalDateTime parse(CharSequence text, DateTimeFormatter formatter)
- static메서드 parse()를 사용
LocalDate date = LocalDate.parse("2001-10-12");
LocalTime time = LocalTime.parse("23:59:59");
LocalDateTime dt = LocalDateTime.parse("2001-10-12T23:59:59");
- ofPattern()을 이용해서 파싱할 수도 있음
DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime endOfYear = LocalDateTime.parse("2015-12-31 23:59:59", pattern);
참고 - Java의 정석 3rd Edition (저자 : 남궁성, 출판 : 도우출판)