Date, Calendar
java 1.0에서는 날짜를 표기하기 위해서 Date 클래스를 만들었다.
java.util.Date는 문제가 많다.
- 특정 시점을 날짜가 아닌 밀리초 단위로 표현한다.
- 기준이 1900년이다.
- 1일은 1로 표기하고 1월은 0으로 표기한다.
- mutable하다
Date date = new Date(117, 8, 21);
를 출력하면 Thu Sep 21 00:00:00 CET 2017 라고 나오는데
2017년이 117로 써야 하고 9월인데 8로 써야 하고
CET (중앙유럽시간대)를 쓰니까 뭐 이거 불편한게 이만저만이 아니다.
그래서 java 1.1에서 java.util.Calendar를 만들었다.
이것도 문제가 많다.
- 여전히 달은 0부터 시작했다
- mutable하다
LocalDate
java 8에서 Joda-Time이라는 third party library에 있던 기능을 많이 추가했다. LocalDate는 시간을 제외한 날짜 yyyy-mm-dd 를 표현한다.
LocalDate localDate = LocalDate.of(2020, 7, 4);
int year = localDate.getYear(); // 2020
Month month = localDate.getMonth(); // JULY
int day = localDate.getDayOfMonth(); // 4
DayOfWeek dow = localDate.getDayOfWeek(); // SATURDAY
int len = localDate.lengthOfMonth(); // 31 (7월의 일 수)
boolean leap = localDate.isLeapYear(); // false 윤년 여부
ChronoField라는 enum을 써서도 값을 가져올 수 있다.
int yearChronoField = localDate.get(ChronoField.YEAR);
int monthChronoField = localDate.get(ChronoField.MONTH_OF_YEAR);
int dayChronoField = localDate.get(ChronoField.DAY_OF_MONTH);
하지만 뭐 getYear() 같은 함수들이 있는데 쓸일 있을까 싶다.
LocalTime
시분초를 나타낼 때는 LocalTime을 쓸 수 있다.
LocalTime time = LocalTime.of(13, 45, 20); // 13:45:20
int hour = time.getHour(); // 13
int minute = time.getMinute(); // 45
int second = time.getSecond(); // 20
String을 파싱하는 방법으로도 인스턴스를 만들 수 있다.
LocalDate date = LocalDate.parse("2020-07-04");
LocalTime time = LocalTime.parse("13:45:20");
LocalDateTime
날짜와 시간을 모두 포함할 때 쓰는 클래스이다. 실질적으로 Date는 LocalDateTime으로 대체된다고 생각하면 될 것 같다. LocalDateTime 내부에 LocalDate와 LocalTime이 필드로 정의되어 있다.
LocalDateTime dt1 = LocalDateTime.of(2020, Month.JULY, 4, 21, 13, 45, 20);
LocalDateTime dt2 = LocalDateTime.of(localDate, localTime);
LocalDateTime dt3 = localDate.atTime(13, 45, 20);
LocalDateTime dt4 = localDate.atTime(localTime);
LocalDateTime dt5 = localTime.atDate(localDate);
LocalDateTime에서 LocalDate나 LocalTime만 따로 추출할 수도 있다.
LocalDate date1 = dt1.toLocalDate();
LocalTime time1 = dt1.toLocalTime();
Duration, Period
지속시간과 시간 간격을 Duration과 Period로 나타낼 수 있다.
Duration threeMinutes = Duration.ofMinutes(3);
Duration threeMins = Duration.of(3, ChronoUnit.MINUTES);
Period tenDays = Period.ofDays(10);
Period threeWeeks = Period.ofWeeks(3);
Period twoYearsSixMonthsOneDay = Period.of(2, 6, 1);
날짜 조정하기
java.time API 들은 immutable하기 때문에 변경처럼 보이지만 실제로는 새로운 객체를 만드는 것이다.
날짜를 특정 값으로 설정하기
LocalDate date1 = LocalDate.of(2020, 7, 4); // 2020-07-04
LocalDate date2 = date1.withYear(2011); // 2011-07-04
LocalDate date3 = date2.withDayOfMonth(25); // 2011-07-25
LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 2); // 2011-02-25
날짜를 상대 값으로 바꾸기
LocalDate date1 = LocalDate.of(2020, 7, 4); // 2020-07-04
LocalDate date2 = date1.plusWeeks(1); // 2020-07-11
LocalDate date3 = date2.minusYears(6); // 2014-07-11
LocalDate date4 = date3.plus(6, ChronoUnit.MONTHS); // 2015-01-11
Formatting
포매팅과 관련된 패키지가 새로 추가되었다. java.time.format이며 DateTimeFormatter 에서는 여러 포맷의 상수를 미리 정의하고 있다.
LocalDate date = LocalDate.of(2014, 3, 18);
String s1 = date.format(DateTimeFormatter.BASIC_ISO_DATE); // 20140318
String s2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE); // 2014-03-18
custom format은 다음과 같이 하게 되면 된다.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDate date1 = LocalDate.of(2014, 3, 18);
String formattedDate = date1.format(formatter);
LocalDate date2 = LocalDate.parse(formattedDate, formatter);
System.out.println(formattedDate);
DateTimeFormatter는 기존의 java.util.DateFormat 클래스와 달리 모든 스레드에서 안전하다.
시간대 사용하기
글로벌 서비스를 만들게 된다면 사용할거라고 보는데 timezone을 고려한 DateTime이라고 보면 된다.
ZonedDateTime은 LocalDateTime과 ZoneId를 포함한 개념의 클래스이다.
ZoneId romeZone = ZoneId.of("Europe/Rome");
LocalDate date = LocalDate.of(2014, Month.MARCH, 18);
ZonedDateTime zdt1 = date.atStartOfDay(romeZone);
LocalDateTime dateTime = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45);
ZonedDateTime zdt2 = dateTime.atZone(romeZone);
Instant instant = Instant.now();
ZonedDateTime zdt3 = instant.atZone(romeZone);
'Programming > Java' 카테고리의 다른 글
Modern Java In Action 정리 - 13 디폴트 메서드 (0) | 2020.07.11 |
---|---|
Modern Java In Action 정리 - 11 null 대신 Optional 클래스 (0) | 2020.06.27 |
Modern Java In Action 정리 - 10장 람다를 이용한 도메인 전용 언어 (0) | 2020.06.22 |
Modern Java In Action 정리 - 9장 리팩터링, 테스팅, 디버깅 (0) | 2020.06.13 |
Modern Java In Action 정리 - 8장 컬렉션 API 개선 (0) | 2020.06.06 |