티스토리 뷰
java8 이전부터 사용된 Date 객체와 Calendar를 사용하지 말아야 할 이유 (직관적이지 않고 불변이 아닌 가변..)는 찾아보고
이미 java8이 나온지 엄청 지났고 여러 블로그에 정리가 잘 되어있지만 나도 java8부터 추가된 java.time 패키지에 추가된 클래스를 살펴보기로 함.
날짜와 시간 객체에는 크게 5가지가 있다.
LocalDate - 날짜 정보만 제공
LocalTime - 시간 정보만 제공
LocalDateTime - 날짜와 시간 정보를 모두 제공
ZonedDateTime - 특정 타임존(TimeZone)의 날짜와 시간을 제공
Instant - 특정 시점의 Time-Stamp
그리고 이러한 클래스들은 모두 불변 객체이고 Thread-safe 하다.
LocalDate
로컬 날짜 클래스로 날짜 정보만을 저장하고 가져올 수 있다.
LocalDate nowDate = LocalDate.now();
LocalDate targetDate = LocalDate.of(int year, int month, int dayOfMonth);
참고로 새로 추가되는 자바 API의 불변 객체 생성은 대부분이 of()로 시작된다. List.of(...) 이런 식으로
private static void printAllLocalDate() {
LocalDate nowDate = LocalDate.now();
LocalDate targetDate = LocalDate.of(2021, 3, 1);
System.out.println("현재날짜 가져오기 = " + nowDate);
System.out.println("targetDate = " + targetDate);
System.out.println("현재월의 날짜를 얻어옴: " + targetDate.getDayOfMonth());
System.out.println("년도를 가져옴: " + targetDate.getYear());
System.out.println("월을 숫자로 받아옴: " + targetDate.getMonthValue());
System.out.println("월을 가져옴 (Month 열거값): " + targetDate.getMonth());
System.out.println("일자를 가져옴 (DayOfWeek 열거값): " + targetDate.getDayOfWeek());
System.out.println("일년의 몇 번째 일?: " + targetDate.getDayOfYear());
System.out.println("윤년여부: "+ targetDate.isLeapYear()); //2021년은 윤년이 아니다.
System.out.println("년도 더하기: " + targetDate.plusYears(1));
System.out.println("월 더하기: " + targetDate.plusMonths(1));
System.out.println("주 더하기: " + targetDate.plusWeeks(1));
System.out.println("일 더하기: " + targetDate.plusDays(1));
}
//결과
현재날짜 가져오기 = 2021-03-25
targetDate = 2021-03-01
현재월의 날짜를 얻어옴: 1
년도를 가져옴: 2021
월을 숫자로 받아옴: 3
월을 가져옴 (Month 열거값): MARCH
일자를 가져옴 (DayOfWeek 열거값): MONDAY
일년의 몇 번째 일?: 60
윤년여부: false
년도 더하기: 2022-03-01
월 더하기: 2021-04-01
주 더하기: 2021-03-08
일 더하기: 2021-03-02
LocalTime
로컬 시간 클래스로 시간 정보만을 저장하고 가져올 수 있다.
LocalTime nowTime = LocalTime.now();
LocalTime.of(int hour, int minute, int second, int nanoOfSecond)
예제 코드
private static void printAllLocalTime() {
LocalTime nowTime = LocalTime.now();
LocalTime targetTime = LocalTime.of(12, 35, 33,9999);
System.out.println("현재시간 가져오기: " + nowTime);
System.out.println("targetTime = " + targetTime);
System.out.println("시간: "+targetTime.getHour());
System.out.println("분: " + targetTime.getMinute());
System.out.println("초: " + targetTime.getSecond());
System.out.println("나노초: " + targetTime.getNano());
System.out.println("시간 더하기: " + targetTime.plusHours(1));
System.out.println("분 더하기: " + targetTime.plusMinutes(1));
System.out.println("초 더하기: " + targetTime.plusSeconds(1));
System.out.println("나노 초 더하기: " + targetTime.plusNanos(1));
System.out.println("시간 빼기: " + targetTime.minusHours(1));
System.out.println("분 빼기: " + targetTime.minusMinutes(1));
System.out.println("초 빼기: " + targetTime.minusSeconds(1));
System.out.println("나노 초 빼기: " + targetTime.minusNanos(1));
}
//결과
현재시간 가져오기: 11:31:31.481466
targetTime = 12:35:33.000009999
시간: 12
분: 35
초: 33
나노초: 9999
시간 더하기: 13:35:33.000009999
분 더하기: 12:36:33.000009999
초 더하기: 12:35:34.000009999
나노 초 더하기: 12:35:33.000010
시간 빼기: 11:35:33.000009999
분 빼기: 12:34:33.000009999
초 빼기: 12:35:32.000009999
나노 초 빼기: 12:35:33.000009998
LocalDateTime
클래스명에서 알 수가 있듯이 LocalDate와 LocalTime을 모두 필요로 할 때 사용하는 클래스이다.
날짜와 시간정보가 모두 필요할 때 사용하면 된다. LocalDate와 LocalTime을 합친 클래스라고 생각하면 된다.
LocalDateTime currentDateTime = LocalDateTime.now();
LocalDateTime targetDateTime = LocalDateTime.of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond);
예제 코드는 따로 없다. 왜냐하면 LocalDate와 LocalTime에서 제공하는 메서드는 모두 제공하기 때문이다.
private static void printAllLocalDateTime() {
//LocalDate와 LocalTime을 합친 LocalDateTime이 있다.
//날짜와 시간정보가 모두 필요할때 사용한다.
LocalDateTime nowLocalDateTime = LocalDateTime.now();
LocalDateTime targetLocalDateTime = LocalDateTime.of(2021, 3, 1, 12, 35);
System.out.println("nowLocalDateTime = " + nowLocalDateTime);
System.out.println("기존 LocalDate와 LocalTime이 제공하는 메서드를 모두 사용할 수 있다.");
}
그런데 LocalDateTime을 LocalDate 또는 LocalTime으로 변환하려면 아래와 같이 사용하면 된다.
LocalDateTime nowLocalDateTime = LocalDateTime.now();
LocalDateTime targetLocalDateTime = LocalDateTime.of(2021, 3, 1, 12, 35);
//LocalDateTime을 LocalDate 또는 LocalTime으로 변환 하는 방법
LocalDate localDate = targetLocalDateTime.toLocalDate();
LocalTime localTime = targetLocalDateTime.toLocalTime();
System.out.println("localDate = " + localDate);
System.out.println("localTime = " + localTime);
//결과
localDate = 2021-03-01
localTime = 12:35
ZonedDateTime
ISO-8601 달력 시스템에서 정의하고 있는 타임존(time-zone)의 날짜와 시간을 저장하는 클래스이다.
표준 시간이 같은 지역을 묶어서 시간대 규칙 집합을 정의한다. ZoneRules 클래스에는 약 40개 정도의 시간대가 있다.
다음처럼 지역 ID로 특정 ZoneID를 구분한다.
한 마디로 날짜와 시간 정보를 포함하고 그 지역의 시간대를 추가한 것이 ZonedDateTime 이다.
ZoneId seoulZone = ZoneId.of("Asia/Seoul");
ZonedDateTime SeoulDateTime = ZonedDateTime.now(seoulZone);
출력 시에는 맨 뒤에 타임존에 대한 정보가 추가적으로 붙는다.
특정 지역의 시간대를 알고 싶을 때 사용할 수 있다.
지역 ID는 '{지역}/{도시}' 형식으로 이루어진다.
ZoneId의 새로운 메서드인 toZoneId로 기존의 TimeZone 객체를 ZoneId 객체로 변환할 수 있다.
ZoneId zoneId = TimeZone.getDefault().toZoneId();
System.out.println(zoneId); //Asia/Seoul
ZoneId 객체를 얻은 다음 LocalDate, LocalDateTime, Instatnt를 이용해서 ZonedDataTime 인스턴스로 변환할 수 있다.
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);
System.out.println("zdt1 = " + zdt1);
System.out.println("zdt2 = " + zdt2);
System.out.println("zdt3 = " + zdt3);
//결과
zdt1 = 2014-03-18T00:00+01:00[Europe/Rome]
zdt2 = 2014-03-18T13:45+01:00[Europe/Rome]
zdt3 = 2021-03-25T05:30:40.658385+01:00[Europe/Rome]
Instant 클래스
사람은 보통 주, 날짜, 시간, 분으로 날짜와 시간을 계산하지만 기계에서는 이와 같은 단위로 시간을 표현하기 어렵다.
기계의 관점에서는 연속된 시간에서 특정 지점을 하나의 큰 수로 표현하는 것이 가장 자연스러운 시간 표현 방법이다.
Instant 클래스에 서는 이와 같은 기계적인 관점에서 시간을 표현한다.
주로 특정한 두 시점 간의 시간적 우선순위를 따질 때 사용한다.
Instant 클래스는 나노초(10억 분의 1초)의 정밀도를 제공한다.
그리고 Instant 클래스는 항상 UTC(협정세계시) 를 기준으로 하기 때문에 LocalTime과는 차이가 있다.
한국의 시간을 알려면 UTC 시간에 +09:00 해보면 된다. 한국 시간은 UTC 시간 기준으로 9시간 이후다.
Instant now = Instant.now();
System.out.println("now = " + now);
코드를 실행해보면 UTC 의 시간이 나오는데 여기서 9시간을 더하면 한국 시간이다.
private static void printAllInstant() {
Instant instant1 = Instant.now();
Instant instant2 = Instant.now();
if (instant1.isBefore(instant2)) {
System.out.println("instant1이 빠릅니다.");
} else if (instant1.isAfter(instant2)) {
System.out.println("instant1이 늦습니다.");
} else {
System.out.println("동일한 시간입니다.");
}
System.out.println("차이(nanos): " + instant1.until(instant2, ChronoUnit.NANOS));
}
참고
모던자바인액션 www.yes24.com/Product/Goods/77125987?OzSrank=1
- Total
- Today
- Yesterday
- 북리뷰
- input
- springboot
- svn
- Bash tab
- LocalDateTime
- Github Status
- mybatis config
- Linux
- k8s
- Kotlin
- elasticsearch
- config-location
- mybatis
- localtime
- 베리 심플
- 오라클
- LocalDate
- intellij
- window
- rocky
- maven
- oracle
- JavaScript
- docker
- Mac
- Spring Security
- Spring
- jQuery
- Java
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |