- 1 LocalDate란?
- 2 LocalDate의 기본 연산
- 3 연도, 월, 일, 요일 가져오기
- 4 날짜 계산 (덧셈 및 뺄셈)
- 5 고급 작업: 특정 날짜 조정
- 6 LocalDate와 LocalDateTime 작업하기
- 7 예외 처리와 모범 사례
- 8 LocalDate의 실용적인 사용 사례
- 9 FAQ (Frequently Asked Questions)
- 9.1 Q1. What is the difference between LocalDate and Date?
- 9.2 Q2. Can LocalDate handle time zones?
- 9.3 Q3. What is the difference between LocalDate and LocalDateTime?
- 9.4 Q4. Can I parse custom date formats?
- 9.5 Q5. How should I handle invalid dates or formats?
- 9.6 Q6. Can I compare two LocalDate instances?
- 10 Conclusion
LocalDate란?
Java에서 날짜 처리는 8버전 이후 크게 발전했습니다. 이 발전의 중심에 LocalDate가 있습니다. LocalDate는 불변 객체로, 시간이나 시간대 개념 없이 날짜만 (년, 월, 일, 예: 2025-06-26) 을 나타냅니다. 오늘 날짜나 특정 달력을 간단하고 안전하게 다룰 수 있게 해줍니다.
레거시 날짜 클래스와의 차이점
Java 8 이전에는 java.util.Date와 java.util.Calendar 같은 클래스가 일반적으로 사용되었습니다. 그러나 이들 클래스는 오류가 발생하기 쉬운 설계(예: 0부터 시작하는 월), 스레드 안전성 부족, 직관적이지 않은 API 등 여러 문제점을 가지고 있었습니다. 그 결과 버그나 예기치 않은 동작이 자주 발생했습니다.
LocalDate는 이러한 문제를 해결하고 다음과 같은 특징을 제공합니다:
- 년, 월, 일만 명시적으로 관리 (예: 2025년 6월 26일)
- 불변 객체 (값을 변경할 수 없어 안전함)
- 직관적인 메서드명과 API 설계 (예: 다음 날을 위한
plusDays(1), 월 번호를 위한getMonthValue()) - 시간대와 무관 (시스템이나 서버 설정에 관계없이 일관된 동작)
언제 LocalDate를 사용해야 할까요?
LocalDate는 날짜를 명확히 다루고 싶고, 시간 정보가 필요 없으며, 날짜 연산을 안전하고 쉽게 구현하고자 할 때 이상적입니다. 일반적인 사용 사례는 다음과 같습니다:
- 생일이나 기념일처럼 시간 없이 날짜만 기록
- 일정, 마감일, 기한 관리
- 마감일이나 남은 일수 계산
이러한 이유로 LocalDate는 Java에서 날짜 처리를 위한 새로운 표준이라고 할 수 있습니다. 다음 섹션에서는 LocalDate의 기본 사용법과 초기화 방법을 자세히 설명합니다.
LocalDate의 기본 연산
LocalDate는 직관적이고 간단한 API를 제공하여 날짜를 조작합니다. 이 섹션에서는 흔히 사용되는 기능들을 구체적인 예시와 함께 설명합니다.
현재 날짜 가져오기
오늘 날짜를 얻으려면 LocalDate.now() 메서드를 사용합니다. 이 메서드는 현재 시스템 날짜(시간대와 무관)를 LocalDate 인스턴스로 반환합니다.
import java.time.LocalDate;
LocalDate today = LocalDate.now();
System.out.println(today); // Example: 2025-06-26
특정 날짜 만들기
과거 혹은 미래의 임의 날짜를 만들려면 LocalDate.of(int year, int month, int dayOfMonth) 를 사용합니다. 이를 통해 2024년 12월 31일과 같이 자유롭게 날짜를 생성할 수 있습니다.
LocalDate specialDay = LocalDate.of(2024, 12, 31);
System.out.println(specialDay); // 2024-12-31
문자열에서 날짜 파싱하기
“2023-03-15”와 같은 문자열에서 LocalDate를 만들려면 LocalDate.parse(String text) 메서드를 사용합니다. 문자열이 표준 ISO 형식(“YYYY-MM-DD”)을 따르는 경우 별도의 설정이 필요하지 않습니다.
LocalDate parsedDate = LocalDate.parse("2023-03-15");
System.out.println(parsedDate); // 2023-03-15
사용자 정의 형식으로 파싱하기 (보충)
“2023/03/15”와 같이 사용자 정의 형식의 날짜를 처리해야 할 경우 DateTimeFormatter와 parse()를 결합하면 됩니다.
import java.time.format.DateTimeFormatter;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDate formattedDate = LocalDate.parse("2023/03/15", formatter);
System.out.println(formattedDate); // 2023-03-15
위와 같이 LocalDate의 기본 연산은 직관적이고 간단합니다. 현대 Java 코드에서는 날짜 초기화와 변환이 거의 혼란스럽지 않습니다. 다음 장에서는 LocalDate에서 연도, 월, 일, 요일 값을 추출하는 방법을 설명합니다.
연도, 월, 일, 요일 가져오기
LocalDate를 사용하면 날짜 자체뿐만 아니라 연도, 월, 일, 요일과 같은 개별 요소도 쉽게 추출할 수 있습니다. 이 섹션에서는 이러한 흔히 사용되는 요소들을 어떻게 가져오는지 설명합니다.
연도, 월, 일 가져오기
LocalDate 인스턴스에서 각 요소를 추출하려면 전용 getter 메서드를 사용합니다.
LocalDate date = LocalDate.of(2025, 6, 26);
int year = date.getYear(); // Year (e.g. 2025)
int month = date.getMonthValue(); // Month as a number (1–12, e.g. 6)
int day = date.getDayOfMonth(); // Day of month (1–31, e.g. 26)
System.out.println("Year: " + year);
System.out.println("Month: " + month);
System.out.println("Day: " + day);
월 및 요일 이름 가져오기
LocalDate는 월 및 요일 이름을 가져오는 것도 지원하며, 텍스트 형태의 표현이 필요할 때 유용합니다.
- 월 이름 (영어 표현)
getMonth()를 사용하면Month열거형 값(예: JUNE)을 반환합니다.import java.time.Month; Month monthName = date.getMonth(); // JUNE (uppercase English) System.out.println(monthName);
- 요일 이름
getDayOfWeek()는DayOfWeek열거형(예: THURSDAY)을 반환합니다.import java.time.DayOfWeek; DayOfWeek dayOfWeek = date.getDayOfWeek(); // THURSDAY (uppercase English) System.out.println(dayOfWeek);
일본어로 월 및 요일 이름 표시하기
월이나 요일 이름을 영어가 아닌 일본어로 표시하고 싶다면, DateTimeFormatter를 사용하여 출력을 맞춤 설정할 수 있습니다.
import java.time.format.DateTimeFormatter;
import java.util.Locale;
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("yyyy年MM月dd日(E)", Locale.JAPANESE);
String formatted = date.format(formatter); // 2025年06月26日(木)
System.out.println(formatted);
검색된 구성 요소 요약
LocalDate의 주요 강점 중 하나는 직관적인 메서드를 사용해 연도, 월, 일, 요일을 가져올 수 있다는 점입니다. 이러한 유연성 덕분에 비즈니스 및 웹 애플리케이션에서 날짜 처리가 훨씬 쉬워집니다.
날짜 계산 (덧셈 및 뺄셈)
일정을 관리하고 마감일을 계산할 때, 일수를 더하거나 빼는 날짜 계산이 자주 필요합니다. LocalDate를 사용하면 “3일 뒤”, “1주일 전”, 혹은 “두 날짜 사이의 차이”와 같은 작업을 안전하고 직관적으로 수행할 수 있습니다.
날짜 더하기
- 일 더하기
LocalDate today = LocalDate.of(2025, 6, 26); LocalDate threeDaysLater = today.plusDays(3); // Three days later System.out.println(threeDaysLater); // 2025-06-29
- 월 또는 연도 더하기
LocalDate nextMonth = today.plusMonths(1); // One month later LocalDate nextYear = today.plusYears(1); // One year later System.out.println(nextMonth); // 2025-07-26 System.out.println(nextYear); // 2026-06-26
날짜 빼기
- 일, 월, 연도 빼기
LocalDate lastWeek = today.minusWeeks(1); // One week earlier LocalDate previousDay = today.minusDays(1); // Previous day System.out.println(lastWeek); // 2025-06-19 System.out.println(previousDay); // 2025-06-25
날짜 간 차이 계산
- 일 수 차이 계산
import java.time.temporal.ChronoUnit; LocalDate start = LocalDate.of(2025, 6, 1); LocalDate end = LocalDate.of(2025, 6, 26); long daysBetween = ChronoUnit.DAYS.between(start, end); // 25 System.out.println(daysBetween); // 25
- 다른 단위(월, 연도)로 차이 계산
long monthsBetween = ChronoUnit.MONTHS.between(start, end); // 0 long yearsBetween = ChronoUnit.YEARS.between(start, end); // 0
요약
LocalDate의 덧셈 및 뺄셈 메서드를 사용하면 “다음 달 마감일”이나 “마지막 이벤트 이후 경과 일수”와 같은 일반적인 날짜 계산을 쉽게 구현할 수 있습니다.
LocalDate는 불변 객체이므로 원본 인스턴스는 절대 변경되지 않습니다. 각 연산은 새로운 LocalDate 인스턴스를 반환하여 안전한 날짜 처리를 보장합니다.
고급 작업: 특정 날짜 조정
실제 날짜 처리에서는 단순한 더하기나 빼기가 충분하지 않은 경우가 많습니다. 일반적인 요구 사항으로는 “월의 마지막 날”이나 “다음 달의 첫 번째 날”을 구하는 것이 있습니다. LocalDate는 이러한 조정을 위한 편리한 API를 제공합니다.
TemporalAdjuster 사용하기
LocalDate를 사용하면 with() 메서드와 TemporalAdjuster를 결합하여 “월말”, “월초”, 또는 “다음 특정 요일”과 같은 직관적인 작업을 수행할 수 있습니다. TemporalAdjusters 클래스에 내장된 조정기들이 제공됩니다.
월의 첫 번째와 마지막 날 구하기
- 월의 마지막 날 구하기
import java.time.LocalDate; import java.time.temporal.TemporalAdjusters; LocalDate date = LocalDate.of(2025, 6, 26); LocalDate endOfMonth = date.with(TemporalAdjusters.lastDayOfMonth()); System.out.println(endOfMonth); // 2025-06-30
- 월의 첫 번째 날 구하기
LocalDate startOfMonth = date.with(TemporalAdjusters.firstDayOfMonth()); System.out.println(startOfMonth); // 2025-06-01
요일에 기반한 조정
요일에 기반한 조정—예를 들어 “월의 두 번째 월요일” 또는 “다음 금요일”—도 구현하기 쉽습니다.
- 다음 금요일 구하기
import java.time.DayOfWeek; LocalDate nextFriday = date.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)); System.out.println(nextFriday); // 2025-06-27
- 현재 월의 두 번째 월요일 구하기
LocalDate secondMonday = date.with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.MONDAY)); System.out.println(secondMonday); // 2025-06-09
연도의 시작 또는 끝으로 조정하기
동일한 접근 방식을 적용하여 연도의 첫 번째 또는 마지막 날을 가져올 수 있습니다.
LocalDate startOfYear =
date.with(TemporalAdjusters.firstDayOfYear());
LocalDate endOfYear =
date.with(TemporalAdjusters.lastDayOfYear());
System.out.println(startOfYear); // 2025-01-01
System.out.println(endOfYear); // 2025-12-31
사용자 정의 조정기 생성하기
특정 비즈니스 규칙에 기반한 사용자 정의 날짜 조정 로직이 필요하다면, TemporalAdjuster 인터페이스를 직접 구현할 수 있습니다.
LocalDate와 TemporalAdjusters를 결합하면 복잡한 날짜 계산도 직관적이고 유연해집니다. 이는 마감일이나 비즈니스 특정 일정을 처리할 때 특히 유용합니다.

LocalDate와 LocalDateTime 작업하기
Java 날짜 및 시간 API(java.time 패키지) 내에서 LocalDate는 날짜만을 나타내고, LocalDateTime은 날짜와 시간을 모두 나타냅니다. 실제로 개발자들은 이 두 유형 간 변환을 자주 필요로 합니다. 이 섹션에서는 이러한 변환을 수행하는 방법을 설명합니다.
LocalDate를 LocalDateTime으로 변환하기
LocalDate에 시간 정보를 추가하여 LocalDateTime으로 변환하려면 atTime() 또는 atStartOfDay()를 사용합니다.
- 특정 시간 추가하기
import java.time.LocalDate; import java.time.LocalDateTime; LocalDate date = LocalDate.of(2025, 6, 26); LocalDateTime dateTime = date.atTime(14, 30, 0); // 2025-06-26 14:30:00 System.out.println(dateTime);
- 하루 시작 시점의 LocalDateTime 생성하기
LocalDateTime startOfDay = date.atStartOfDay(); // 2025-06-26T00:00 System.out.println(startOfDay);
LocalDateTime을 LocalDate로 변환하기
LocalDateTime에서 날짜 부분만 추출하려면 toLocalDate() 메서드를 사용합니다.
import java.time.LocalDateTime;
LocalDateTime dateTime =
LocalDateTime.of(2025, 6, 26, 14, 30);
LocalDate dateOnly = dateTime.toLocalDate();
System.out.println(dateOnly); // 2025-06-26
LocalDate와 LocalTime 결합하기
LocalDate와 LocalTime을 결합하여 LocalDateTime을 생성할 수도 있습니다.
import java.time.LocalTime;
LocalTime time = LocalTime.of(9, 0);
LocalDateTime combined =
date.atTime(time); // 2025-06-26T09:00
System.out.println(combined);
요약
atTime()또는atStartOfDay()를 사용하여LocalDate를LocalDateTime으로 변환하기toLocalDate()를 사용하여LocalDateTime을LocalDate로 변환하기- 날짜와 시간을 분리하고 결합하는 것은 실제 시스템에서 일반적입니다
예외 처리와 모범 사례
날짜 처리는 잘못된 값이나 형식을 사용하면 예기치 않은 예외를 쉽게 발생시킬 수 있습니다. LocalDate를 사용하더라도 존재하지 않는 날짜나 파싱 오류로 인해 예외가 발생할 수 있습니다. 이 섹션에서는 일반적인 예외와 이를 안전하게 처리하는 모범 사례를 설명합니다.
존재하지 않는 날짜 지정
존재하지 않는 날짜를 생성하려고 시도하면—예를 들어 2023년 2월 30일—DateTimeException이 발생합니다.
import java.time.LocalDate;
// Example that throws an exception
LocalDate invalidDate = LocalDate.of(2023, 2, 30);
이러한 경우에는 예외를 적절히 catch하여 처리하는 것이 중요합니다.
try {
LocalDate invalidDate = LocalDate.of(2023, 2, 30);
} catch (DateTimeException e) {
System.out.println("An invalid date was specified: " + e.getMessage());
}
문자열 파싱 중 예외
LocalDate.parse()를 사용할 때 문자열 형식이 유효하지 않거나 날짜 자체가 존재하지 않으면 DateTimeParseException이 발생합니다.
import java.time.format.DateTimeParseException;
try {
LocalDate date = LocalDate.parse("2023/02/30");
} catch (DateTimeParseException e) {
System.out.println("Failed to parse date: " + e.getMessage());
}
모범 사례
- 입력 값을 미리 검증 사용자 입력을 받을 때, 예외를 방지하기 위해 파싱 전에 형식과 값을 모두 검증하세요.
- 예외를 catch하고 사용자 친화적인 메시지 제공 애플리케이션이 충돌하는 대신, 사용자에게 명확하고 이해하기 쉬운 오류 메시지를 반환하세요.
- 불변성을 활용 LocalDate가 불변이기 때문에, 계산 결과를 기존 인스턴스를 덮어쓰는 대신 항상 새 인스턴스로 취급하세요.
일반적인 함정
- 윤년의 2월 29일 처리
- 유효 범위를 벗어나는 값 지정 (예: 월 = 13, 일 = 0)
- 문자열 파싱 중 형식 불일치
이러한 문제는 초보자에게 특히 흔하므로 추가적인 주의가 필요합니다.
LocalDate의 실용적인 사용 사례
LocalDate는 단순한 날짜 저장에 국한되지 않으며—실제 비즈니스 시스템과 애플리케이션에서 널리 사용됩니다. 아래는 여러 실용적인 예제입니다.
생일과 나이 계산
출생일에 기반한 사람의 나이를 계산하는 것은 고전적인 사용 사례입니다. LocalDate와 Period를 함께 사용하면 이것이 쉬워집니다.
import java.time.LocalDate;
import java.time.Period;
LocalDate birthDay = LocalDate.of(1990, 8, 15);
LocalDate today = LocalDate.now();
Period period = Period.between(birthDay, today);
int age = period.getYears();
System.out.println("Age: " + age);
마감일과 납기 관리
LocalDate는 작업 관리 시스템에서 마감일까지 남은 일수를 계산하는 등의 용도로도 유용합니다.
LocalDate deadline = LocalDate.of(2025, 7, 10);
long daysLeft =
java.time.temporal.ChronoUnit.DAYS.between(today, deadline);
System.out.println("Days remaining until deadline: " + daysLeft);
스케줄링과 달력 생성
“매월 두 번째 월요일에 회의”와 같은 요구사항은 TemporalAdjusters를 사용하면 쉽게 구현할 수 있습니다.
import java.time.DayOfWeek;
import java.time.temporal.TemporalAdjusters;
LocalDate secondMonday =
LocalDate.of(2025, 7, 1)
.with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.MONDAY));
System.out.println("Second Monday of July: " + secondMonday);
웹 시스템과 API에서의 날짜 검증
LocalDate는 백엔드 시스템에서 날짜 입력을 검증하는 데 자주 사용됩니다. 예를 들어, 미래 날짜나 특정 범위보다 오래된 날짜를 거부할 수 있습니다.
LocalDate inputDate = LocalDate.parse("2024-12-31");
LocalDate tenYearsAgo = today.minusYears(10);
if (inputDate.isAfter(today)) {
System.out.println("Future dates are not allowed");
} else if (inputDate.isBefore(tenYearsAgo)) {
System.out.println("Please specify a date within the last 10 years");
} else {
System.out.println("The date is valid");
}
Adoption in Training and Production Systems
As seen in many competing articles, LocalDate is now a standard topic in Java training programs and onboarding curricula. It is also widely used in production systems such as banking business-day calculations and inventory management.
FAQ (Frequently Asked Questions)
Q1. What is the difference between LocalDate and Date?
A.
LocalDate is part of the modern Java Date and Time API introduced in Java 8 and represents only a date (year, month, day). java.util.Date, on the other hand, is a legacy class that includes time and internally manages values in milliseconds.
LocalDate is immutable, intuitive, and thread-safe, and is recommended for modern Java development.
Q2. Can LocalDate handle time zones?
A.
LocalDate itself does not contain time zone information. If time zone support is required, use ZonedDateTime or OffsetDateTime. A common approach is to manage dates with LocalDate first, then convert when time zones become necessary.
Q3. What is the difference between LocalDate and LocalDateTime?
A.
LocalDate represents only a date. LocalDateTime represents both date and time (e.g. 2025-06-26 14:00). Use LocalDate for deadlines or anniversaries, and LocalDateTime for events with precise timestamps.
Q4. Can I parse custom date formats?
A.
Yes. By using DateTimeFormatter, you can parse dates in custom formats.
import java.time.format.DateTimeFormatter;
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDate date =
LocalDate.parse("2025/06/26", formatter);
Q5. How should I handle invalid dates or formats?
A.
Invalid dates or formats cause exceptions such as DateTimeException or DateTimeParseException. Use try-catch blocks, validate input in advance, and provide clear error messages to users.
Q6. Can I compare two LocalDate instances?
A.
Yes. Use isAfter(), isBefore(), or isEqual().
LocalDate date1 = LocalDate.of(2025, 6, 26);
LocalDate date2 = LocalDate.of(2025, 7, 1);
if (date1.isBefore(date2)) {
System.out.println("date1 is earlier than date2");
}
Conclusion
This article provided a comprehensive explanation of Java LocalDate, from basic concepts to advanced use cases. Key points include:
- What LocalDate is An immutable date-only object introduced in Java 8 that fixes the flaws of legacy Date and Calendar classes.
- Basic usage Retrieving the current date, creating specific dates, and parsing strings using simple APIs.
- Extracting components Easily retrieving year, month, day, and weekday values.
- Date calculations Intuitive addition, subtraction, and difference calculations.
- Date adjustments Using TemporalAdjusters to handle end-of-month, weekdays, and more.
- Integration with time APIs Flexible conversion between LocalDate, LocalDateTime, and LocalTime.
- Safe handling and best practices Proper exception handling and validation for robust systems.
- Real-world applications and FAQs Practical examples such as age calculation, deadlines, scheduling, and validation.
Next Steps
Once you master LocalDate, date handling becomes straightforward and reliable. For more advanced scenarios—such as time zones, period calculations, and formatting—consider learning ZonedDateTime, Period, and DateTimeFormatter.
Use LocalDate as a powerful foundation to build clean, robust, and maintainable Java applications.
