(2) 시간, 날짜 관련 API(LocalTime, LocalDate, LocalDateTime)
1. 시간, 날짜 관련 클래스
1-1. LocalTime
시간 정보만을 나타내는 클래스로 시(hour), 분(minute), 초(second), 나노초(nanoOfSecond)를 포함하며 시간 오프셋(TImeZone)에 대한 정보는 없습니다.
- 시간 관련 클래스
- 시간 오프셋(TimeZone)에 대한 정보는 없다.
- 시(hour), 분(minute), 초(second), 나노초(nanoOfSecond)의 값을 갖는다
- ex) 19:35:25.830054400
1-2. LocalDate
날짜 정보만을 나타내는 클래스로 연(year), 달(month), 날(dayOfMonth)의 포함하며, 특정 시간대나 시간 오프셋(TimeZone)에 대한 정보는 없습니다.
- 날짜 관련 클래스
- 시간 오프셋(TimeZone)에 대한 정보는 없다.
- 연(year), 달(month), 날(dayOfMonth)의 값을 갖는다
- ex) 2023-08-19
1-3. LocalDateTime
날짜와 시간 정보를 모두 나타내는 클래스로 연(year), 달(month), 날(dayOfMonth), 시(hour), 분(minute), 초(second), 나노초(nanoOfSecond)를 포함하며, 시간 오프셋(TimeZone)에 대한 정보는 없습니다.
- 시간, 날짜 관련 클래스
- LocalDate + LocalTime의 값을 갖는다.
- ex) 2023-08-19T19:35:25.830054400
1-4. ZonedDateTime
시간대와 함께 날짜와 시간 정보를 모두 나타내는 클래스로 연(year), 달(month), 날(dayOfMonth), 시(hour), 분(minute), 초(second), 나노초(nanoOfSecond)와 시간 오프셋(TimeZone)에 대한 정보도 포함되어 있습니다. 시간 오프셋을 이용하여 협정 세계시(UTC) 시간으로 변환하거나 타 지역의 시간으로 변환할 수 있습니다.
- 타임존, 시간, 날짜 관련 클래스
- 타임존(ZoneId) + LocalDateTime의 값을 갖는다
- ex) 2023-08-19T19:35:25.830054400+09:00[Asia/Seoul]
1-5. Instant
협정 세계시(UTC) 기준 날짜와 시간 정보를 모두 나타내는 클래스로 연(year), 달(month), 날(dayOfMonth), 시(hour), 분(minute), 초(second), 나노초(nanoOfSecond)에 대한 정보가 포함되어 있으며 협정 세계시(UTC)를 기준으로 하기 때문에 타임존(ZoneId)을 이용하여 원하는 지역의 날짜와 시간 정보를 구할 수 있습니다.
- UTC 기준 시간, 날짜 관련 클래스
- UTC의 시간, 날짜 관련 값을 갖는다.
- ex) 2023-08-19T10:35:25.830054400Z
2. 날짜와 시간에 대한 정보 관련 메서드
클래스 | 리턴타입 | 메서드 | 설명 | |
LocalDateTime ZonedDateTIme |
LocalDate | int | getYear() | 년 |
Month | getMonth() | Month 열거값 | ||
int | getMonthValue() | 월 | ||
int | getDayOfYear() | 년 기준 몇 번째 일 | ||
int | getDayOfMonth() | 월 기준 몇 번째 일 | ||
DayOfWeek | getDayOfWeek() | 요일 | ||
boolean | isLeapYear() | 윤년 여부 (LocalDate에서만 제공) |
||
LocalTime | int | getHour() | 시간 | |
int | getMinute() | 분 | ||
int | getSecond() | 초 | ||
int | getNano() | 나노초 |
LocalDate localDate = LocalDate.of(2023, 8, 19);
LocalTime localTime = LocalTime.of(19, 11, 20, 4500);
log.info("localDate.getYear() = {}", localDate.getYear());
log.info("localDate.getMonth() = {}", localDate.getMonth());
log.info("localDate.getMonthValue() = {}", localDate.getMonthValue());
log.info("localDate.getDayOfYear() = {}", localDate.getDayOfYear());
log.info("localDate.getDayOfMonth() = {}", localDate.getDayOfMonth());
log.info("localDate.getDayOfWeek() = {}", localDate.getDayOfWeek());
log.info("localDate.isLeapYear() = {}", localDate.isLeapYear());
log.info("localTime.getHour() = {}", localTime.getHour());
log.info("localTime.getMinute() = {}", localTime.getMinute());
log.info("localTime.getSecond() = {}", localTime.getSecond());
log.info("localTime.getNano() = {}", localTime.getNano());
log.info("localTime.getLong(ChronoField.HOUR_OF_DAY) = {}", localTime.getLong(ChronoField.HOUR_OF_DAY));
// 결과
localDate.getYear() = 2023
localDate.getMonth() = AUGUST
localDate.getMonthValue() = 8
localDate.getDayOfYear() = 231
localDate.getDayOfMonth() = 19
localDate.getDayOfWeek() = SATURDAY
localDate.isLeapYear() = false
localTime.getHour() = 19
localTime.getMinute() = 11
localTime.getSecond() = 20
localTime.getNano() = 4500
localTime.getLong(ChronoField.HOUR_OF_DAY) = 19
ZonedDateTIme
은 위 LocalDateTime
에서 제공하는 시간, 날짜 관련 메서드뿐만 아니라 시간존(TImeZone)에 대한 정보를 제공하는 메서드가 있습니다.
클래스 | 리턴 타입 | 메서드 | 설명 |
ZonedDateTIme | ZoneId | getZone() | 시간존 ID(ex - "Asia/Seoul") |
ZoneOffset | getOffset() | 오프셋(ex - +09:00) |
ZonedDateTime zonedDateTime = ZonedDateTime.of(
2023, 8, 15,
15, 20, 30, 0,
ZoneId.systemDefault());
log.info("zonedDateTime.getZone() = {}", zonedDateTime.getZone());
log.info("zonedDateTime.getOffset() = {}", zonedDateTime.getOffset());
// 결과
zonedDateTime.getZone() = Asia/Seoul
zonedDateTime.getOffset() = +09:00
3. 날짜와 시간 변경 메서드
3-1. 날짜와 시간 빼거나 더하기
클래스 | 메서드 | 설명 | |
LocalDateTime ZonedDateTime |
LocalDate | minusYear(long years) | 년 빼기 |
minusMonths(long months) | 달 빼기 | ||
minusDays(long days) | 일 빼기 | ||
minusWeeks(long weeks) | 주 빼기 | ||
plusYears(long years) | 년 더하기 | ||
plusMonths(long months) | 달 더하기 | ||
plusWeeks(long weeks) | 주 더하기 | ||
plusDays(long days) | 일 더하기 | ||
LocalTime | minusHours(long hours) | 시간 빼기 | |
minusMinutes(long minutes) | 분 빼기 | ||
minusSeconds(long seconds) | 초 빼기 | ||
minusNanos(long nanos) | 나노초 빼기 | ||
plusHours(long hours) | 시간 더하기 | ||
plusMinutes(long minutes) | 분 더하기 | ||
plusSeconds(long seconds) | 초 더하기 | ||
plusNanos(long nanos) | 나노초 더하기 |
3-2. 날짜와 시간 변경
클래스 | 메서드 | 설명 | |
LocalDateTime ZonedDateTime |
LocalDate | withYear(int year) | 년 변경 |
withMonth(int month) | 월 변경 | ||
withDayOfYear(int day) | 년 기준 일 변경 | ||
withDayOfMonth(int day) | 월 기준 일 변경 | ||
LocalTime | withHour(int hour) | 시간 변경 | |
withMinute(int minute) | 분 변경 | ||
withSecond(int second) | 초 변경 | ||
withNano(int nano) | 나노초 변경 |
3-3. TemporalAdjusters 클래스를 이용한 상대 날짜 구하기
날짜 및 시간 조정을 수행하기 위한 다양한 정적 메서드를 가진 TemporalAdjusters
클래스를 with(TemporalAdjusters adjuster) 메서드에 사용하여 상대적인 날짜를 구할 수 있습니다.
클래스 | 메서드 | 설명 |
TemporalAdjusters | firstDayOfYear() | 해당 연도의 첫 번째 날짜 |
lastDayOfYear() | 해당 연도의 마지막 날짜 | |
firstDayOfNextYear() | 다음 연도의 첫 번째 날짜 | |
firstDayOfMonth() | 해당 월의 첫 번째 날짜 | |
lastDayOfMonth() | 해당 월의 마지막 날짜 | |
firstDayOfNextMonth() | 다음 월의 첫 번째 날짜 | |
firstInMonth(DayOfWeek dayOfWeek) | 해당 월의 첫 번째 특정 요일 날짜 | |
lastInMonth(DayOfWeek dayOfWeek) | 해당 월의 마지막 특정 요일 날짜 | |
next(DayOfWeek dayOfWeek) | 돌아오는 요일 | |
nextOrSame(DayOfWeek dayOfWeek) | 돌아오는 요일(오늘 포함) | |
previous(DayOfWeek dayOfWeek) | 지난 요일 | |
previousOrSame(DayOfWeek dayOfWeek | 지난 요일(오늘 포함) |
LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime firstDayOfYear = localDateTime.with(TemporalAdjusters.firstDayOfYear());
LocalDateTime lastDayOfYear = localDateTime.with(TemporalAdjusters.lastDayOfYear());
LocalDateTime firstDayOfNextYear = localDateTime.with(TemporalAdjusters.firstDayOfNextYear());
LocalDateTime firstDayOfMonth = localDateTime.with(TemporalAdjusters.firstDayOfMonth());
LocalDateTime lastDayOfMonth = localDateTime.with(TemporalAdjusters.lastDayOfMonth());
LocalDateTime firstDayOfNextMonth = localDateTime.with(TemporalAdjusters.firstDayOfNextMonth());
LocalDateTime firstInMonth = localDateTime.with(TemporalAdjusters.firstInMonth(DayOfWeek.SUNDAY));
LocalDateTime lastInMonth = localDateTime.with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY));
LocalDateTime next = localDateTime.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
LocalDateTime nextOrSame = localDateTime.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
LocalDateTime previous = localDateTime.with(TemporalAdjusters.previous(DayOfWeek.SUNDAY));
LocalDateTime previousOrSame = localDateTime.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY));
log.info("localDateTime = {}", localDateTime);
log.info("firstDayOfYear = {}", firstDayOfYear);
log.info("lastDayOfYear = {}", lastDayOfYear);
log.info("firstDayOfNextYear = {}", firstDayOfNextYear);
log.info("firstDayOfMonth = {}", firstDayOfMonth);
log.info("lastDayOfMonth = {}", lastDayOfMonth);
log.info("firstDayOfNextMonth = {}", firstDayOfNextMonth);
log.info("firstInMonth = {}", firstInMonth);
log.info("lastInMonth = {}", lastInMonth);
log.info("next = {}", next);
log.info("nextOrSame = {}", nextOrSame);
log.info("previous = {}", previous);
log.info("previousOrSame = {}", previousOrSame);
// 결과
localDateTime = 2023-08-20T18:10:14.775227400
firstDayOfYear = 2023-01-01T18:10:14.775227400
lastDayOfYear = 2023-12-31T18:10:14.775227400
firstDayOfNextYear = 2024-01-01T18:10:14.775227400
firstDayOfMonth = 2023-08-01T18:10:14.775227400
lastDayOfMonth = 2023-08-31T18:10:14.775227400
firstDayOfNextMonth = 2023-09-01T18:10:14.775227400
firstInMonth = 2023-08-06T18:10:14.775227400
lastInMonth = 2023-08-27T18:10:14.775227400
next = 2023-08-27T18:10:14.775227400
nextOrSame = 2023-08-20T18:10:14.775227400
previous = 2023-08-13T18:10:14.775227400
previousOrSame = 2023-08-20T18:10:14.775227400
4. 날짜와 시간 비교하기
클래스 | 리턴 타입 | 메서드 | 설명 |
LocalDate LocalDateTIme |
boolean | isAfter(ChronoLocalDate other) | 이후 날짜인지 비교 |
isBefore(ChronoLocalDate other) | 이전 날짜인지 비교 | ||
isEqual(ChronoLocalDate other) | 동일 날짜인지 비교 | ||
LocalTime LocalDateTime |
boolean | isAfter(LocalTime other) | 이후 시간인지 비교 |
isBefore(LocalTime other) | 이전 시간인지 비교 | ||
LocalDate | Period | until(ChronoLocalDate endDateExclusive) | 날짜 차이 |
LocalDate LocalTime LocalDateTime |
long | until( Temporal endExclusive, TemporalUnit unit ) |
시간 차이 |
Period | Period | between( LocalDate startDateInclusive, LocalDate endDateExclusive ) |
날짜 차이 |
Duration | Duration | between( LocalDate startDateInclusive, LocalDate endDateExclusive ) |
시간 차이 |
ChronoUnit.YEARS | long | between( Temporal temporal1Inclusive, Temporal temporal2Exclusive ) |
년 차이 |
ChronoUnit.MONTHS | 달 차이 | ||
ChronoUnit.WEEKS | 주 차이 | ||
ChronoUnit.DAYS | 일 차이 | ||
ChronoUnit.HOURS | 시간 차이 | ||
ChronoUnit.SECONDS | 초 차이 | ||
ChronoUnit.MILLIS | 밀리초 차이 | ||
ChronoUnit.NANOS | 나노초 차이 |
LocalDateTime localDateTime1 = LocalDateTime.now();
log.info("localDateTime1 = {}", localDateTime1); // 출력 : 2023-08-20T18:43:40.722188500
LocalDateTime localDateTime2 = localDateTime1.minusDays(1);
log.info("localDateTime2 = {}", localDateTime2); // 출력 : 2023-08-19T18:43:40.722188500
log.info("localDateTime1.isAfter(localDateTime2) = {}", localDateTime1.isAfter(localDateTime2)); // 출력 : true
log.info("localDateTime1.isBefore(localDateTime2) = {}", localDateTime1.isBefore(localDateTime2)); // 출력 : false
log.info("localDateTime1.isEqual(localDateTime2) = {}", localDateTime1.isEqual(localDateTime2)); // 출력 : false
log.info("localDateTime1.isEqual(localDateTime2.plusDays(1) = {}", localDateTime1.isEqual(localDateTime2.plusDays(1))); // 출력 : true
log.info("localDateTime1.until(localDateTime2, ChronoUnit.DAYS) = {}", localDateTime1.until(localDateTime2, ChronoUnit.DAYS)); // 출력 : -1
log.info("localDateTime1.until(localDateTime2, ChronoUnit.HOURS) = {}", localDateTime1.until(localDateTime2, ChronoUnit.HOURS));// 출력 : -24
Period period = Period.between(localDateTime1.toLocalDate(), localDateTime2.toLocalDate());
log.info("period.getDay() = {}", period.getDays()); // 출력 : -1
Duration duration = Duration.between(localDateTime1, localDateTime2);
log.info("duration.toHours = {}", duration.toHours()); // 출력 : -24
log.info("ChronoUnit.YEARS.between(localDateTime1, localDateTime2) = {}", ChronoUnit.YEARS.between(localDateTime1, localDateTime2)); // 출력 : 0
log.info("ChronoUnit.MONTHS.between(localDateTime1, localDateTime2) = {}", ChronoUnit.MONTHS.between(localDateTime1, localDateTime2)); // 출력 : 0
log.info("ChronoUnit.WEEKS.between(localDateTime1, localDateTime2) = {}", ChronoUnit.WEEKS.between(localDateTime1, localDateTime2)); // 출력 : 0
log.info("ChronoUnit.DAYS.between(localDateTime1, localDateTime2) = {}", ChronoUnit.DAYS.between(localDateTime1, localDateTime2)); // 출력 : -1
log.info("ChronoUnit.HOURS.between(localDateTime1, localDateTime2) = {}", ChronoUnit.HOURS.between(localDateTime1, localDateTime2)); // 출력 : -24
log.info("ChronoUnit.SECONDS.between(localDateTime1, localDateTime2) = {}", ChronoUnit.SECONDS.between(localDateTime1, localDateTime2));// 출력 : -86400
log.info("ChronoUnit.MILLIS.between(localDateTime1, localDateTime2) = {}", ChronoUnit.MILLIS.between(localDateTime1, localDateTime2)); // 출력 : -86400000
log.info("ChronoUnit.NANOS.between(localDateTime1, localDateTime2) = {}", ChronoUnit.NANOS.between(localDateTime1, localDateTime2)); // 출력 : -86400000000000
// 결과
localDateTime1 = 2023-08-20T18:43:40.722188500
localDateTime2 = 2023-08-19T18:43:40.722188500
localDateTime1.isAfter(localDateTime2) = true
localDateTime1.isBefore(localDateTime2) = false
localDateTime1.isEqual(localDateTime2) = false
localDateTime1.isEqual(localDateTime2.plusDays(1) = true
localDateTime1.until(localDateTime2, ChronoUnit.DAYS) = -1
localDateTime1.until(localDateTime2, ChronoUnit.HOURS) = -24
period.getDay() = -1
duration.toHours = -24
ChronoUnit.YEARS.between(localDateTime1, localDateTime2) = 0
ChronoUnit.MONTHS.between(localDateTime1, localDateTime2) = 0
ChronoUnit.WEEKS.between(localDateTime1, localDateTime2) = 0
ChronoUnit.DAYS.between(localDateTime1, localDateTime2) = -1
ChronoUnit.HOURS.between(localDateTime1, localDateTime2) = -24
ChronoUnit.SECONDS.between(localDateTime1, localDateTime2) = -86400
ChronoUnit.MILLIS.between(localDateTime1, localDateTime2) = -86400000
ChronoUnit.NANOS.between(localDateTime1, localDateTime2) = -86400000000000
관련 포스팅
'Backend > Java' 카테고리의 다른 글
[Java] ☕ Thread 정리: 메서드, 생명주기, 제어 방법 (0) | 2025.04.07 |
---|---|
[Java] 🧵 Thread 기본 개념 (0) | 2025.04.06 |
[Java] (1) 시간, 날짜 관련 API(LocalTime, LocalDate, LocalDateTime) (0) | 2023.08.19 |
[Java] 자바 8 - 올바른 Optional 사용법 (0) | 2023.08.13 |
[Java] 자바 8 - Optional 사용법 (1) | 2023.07.31 |