JAVA 날짜 처리 방법 정리 – LocalDate, Calendar 차이와 사용법
📌 자바에서 날짜 계산부터 포맷 변환까지 완벽하게 정리했습니다
개발을 하다 보면 날짜와 시간을 다뤄야 하는 경우가 정말 많죠.
예약 기능, 일정 관리, 만료일 계산, 포맷 변경 등 다양한 상황에서 날짜 처리 기능은 꼭 필요합니다.
그런데 생각보다 날짜 관련 API는 복잡하고, 버전에 따라 사용하는 클래스도 다릅니다.
저 역시 예전에 Calendar 객체를 썼다가 헤매기도 했고, 최근에는 java.time.LocalDate를 접하고 나서야 좀 더 명확하게 이해할 수 있었습니다.
오늘은 JAVA에서 날짜를 처리하는 방법을 처음부터 천천히 짚어보며 Calendar와 LocalDate의 차이점, 그리고 각각의 사용법을 실전 예제로 알아보려 해요.
이 글에서는 java.time 패키지의 핵심 클래스인 LocalDate, LocalDateTime을 중심으로, 날짜 연산, 포맷 변경, 과거 방식인 Calendar 클래스와의 차이까지 함께 정리해드립니다.
단순한 이론 설명이 아닌 예제 기반으로 따라 하기 쉽게 구성했으니, 초보 개발자분들도 쉽게 이해하실 수 있을 거예요.
그럼 아래 목차부터 확인해 보시죠!
📋 목차
📅 유용한 LocalDate 클래스 살펴보기
자바 8부터 도입된 LocalDate는 날짜를 보다 직관적으로 처리할 수 있도록 도와주는 클래스입니다.
시간 정보 없이 오직 날짜만을 다루고자 할 때 유용하며, 기존 Date나 Calendar보다 훨씬 간결한 코드 작성이 가능합니다.
예를 들어, 오늘 날짜를 가져오는 것은 단 한 줄로 끝납니다.
import java.time.LocalDate;
public class DateExample {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
System.out.println("오늘 날짜: " + today);
}
}
이 외에도 특정 날짜를 직접 지정하거나, 날짜 연산을 하는 것도 매우 간단합니다.
LocalDate birthDate = LocalDate.of(1995, 7, 15);
LocalDate nextWeek = birthDate.plusWeeks(1);
LocalDate previousDay = birthDate.minusDays(1);
💎 핵심 포인트:
LocalDate는 불변 객체이므로, 연산 결과는 항상 새로운 객체를 반환합니다.
또한 날짜 비교도 매우 직관적입니다.
예를 들어 두 날짜 중 어떤 것이 더 빠른지를 비교하려면 isBefore(), isAfter() 메서드를 활용하면 됩니다.
LocalDate today = LocalDate.now();
LocalDate deadline = LocalDate.of(2025, 12, 31);
if (today.isBefore(deadline)) {
System.out.println("마감일 이전입니다.");
}
이처럼 LocalDate는 날짜 관련 연산을 훨씬 더 읽기 쉬운 코드로 만들 수 있게 도와줍니다.
실무에서는 정산일, 만기일, 일정 관리 등 다양한 곳에 활용되고 있으며, 자바 날짜 처리의 기본 중 기본이라고 할 수 있습니다.
🕰️ LocalDateTime으로 날짜와 시간 동시 처리
LocalDate가 날짜만을 다루는 클래스라면, LocalDateTime은 이름 그대로 날짜와 시간 정보를 함께 처리할 수 있습니다.
특히 타임스탬프나 이벤트 기록, 예약 기능 구현 등에 적합한 클래스입니다.
현재 날짜와 시간을 동시에 얻고 싶다면 다음과 같이 간단하게 사용할 수 있습니다.
import java.time.LocalDateTime;
public class LocalDateTimeExample {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
System.out.println("현재 날짜와 시간: " + now);
}
}
LocalDateTime은 날짜 + 시간을 하나의 객체로 다루며, 시간 연산도 가능합니다.
예를 들어, 2시간 뒤의 시간을 구하거나 특정 시각을 더하고 빼는 것도 가능하죠.
LocalDateTime eventTime = LocalDateTime.of(2025, 10, 5, 14, 30);
LocalDateTime reminderTime = eventTime.minusMinutes(30);
System.out.println("30분 전 알림 시각: " + reminderTime);
이처럼 LocalDateTime은 일정 예약, 알림 설정, 이벤트 시간 계산 등 다양한 상황에서 활용됩니다.
날짜와 시간을 분리해서 처리할 필요 없이, 하나의 객체로 함께 관리할 수 있다는 점이 큰 장점이죠.
💡 TIP: LocalDateTime은 시간대(TimeZone) 정보를 포함하지 않습니다. 만약 시간대까지 고려한 날짜/시간이 필요하다면 ZonedDateTime을 활용하세요.
마지막으로, LocalDateTime은 LocalDate와 LocalTime으로 각각 분리하거나, 반대로 결합하는 것도 가능합니다.
필요에 따라 유연하게 사용할 수 있도록 설계된 점이 자바 8 날짜/시간 API의 큰 매력 중 하나입니다.
📆 옛날 방식, Calendar 클래스의 구조와 한계
LocalDate나 LocalDateTime이 등장하기 이전에는 Calendar 클래스가 날짜를 처리하는 표준 방식이었습니다.
java.util 패키지에 포함되어 있으며, Date 클래스와 함께 오랫동안 사용되어 왔죠.
그러나 Calendar는 설정 방식이 복잡하고 직관성이 떨어지는 단점이 많았습니다.
예를 들어 날짜를 설정하고 출력하려면 아래와 같은 과정을 거쳐야 했습니다.
import java.util.Calendar;
public class CalendarExample {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.set(2025, Calendar.DECEMBER, 25);
System.out.println("설정된 날짜: " + cal.getTime());
}
}
위 예제에서 보이듯이, 월(Month)은 0부터 시작하기 때문에 12월을 지정하려면 Calendar.DECEMBER (== 11)로 설정해야 합니다.
이런 방식은 실수하기 쉬우며, 날짜 계산이나 비교 시에도 코드가 복잡해지는 문제가 있었습니다.
⚠️ 주의: Calendar는 mutable(변경 가능) 객체이므로, 같은 객체를 여러 메서드에서 공유할 경우 예기치 못한 버그가 발생할 수 있습니다.
또한 스레드 안전성(Thread-safety) 측면에서도 Calendar는 안전하지 않기 때문에, 멀티스레드 환경에서는 별도의 동기화 처리가 필요합니다.
이러한 문제점들 때문에 Java 8 이후로는 java.time 패키지 기반의 날짜 처리 방식이 권장되고 있습니다.
💡 TIP: 기존 코드가 Calendar 기반이라면, 가능하다면 점진적으로 LocalDate/LocalDateTime으로 마이그레이션하는 것이 좋습니다.
물론 레거시 시스템 유지보수나 일부 외부 라이브러리에서는 여전히 Calendar를 사용할 수밖에 없는 상황도 있습니다.
이럴 경우에는 java.util.GregorianCalendar와 Date → LocalDate 변환 방식에 대해 익혀두면 큰 도움이 됩니다.
🔁 날짜 더하고 빼기 – 날짜 계산 방법
날짜를 다루는 데 있어 가장 자주 사용하는 기능 중 하나는 바로 날짜 계산입니다.
예를 들어, 며칠 뒤의 날짜를 계산하거나, 일주일 전의 날짜를 구하는 경우가 이에 해당하죠.
자바 8의 LocalDate 및 LocalDateTime 클래스는 이런 계산을 매우 직관적으로 할 수 있게 도와줍니다.
다음은 LocalDate에 날짜 연산을 적용하는 기본 예제입니다.
LocalDate today = LocalDate.now();
LocalDate nextWeek = today.plusWeeks(1);
LocalDate tenDaysAgo = today.minusDays(10);
System.out.println("1주일 뒤: " + nextWeek);
System.out.println("10일 전: " + tenDaysAgo);
기간 단위는 days, weeks, months, years까지 다양하게 지원되며, plus()나 minus()를 사용해 자유롭게 연산할 수 있습니다.
💎 핵심 포인트:
LocalDate는 불변(Immutable)이므로, 연산을 해도 원본 날짜 객체는 변하지 않고, 항상 새로운 객체가 반환됩니다.
또한 날짜 간 차이를 계산할 때는 Period 클래스를 활용할 수 있습니다.
예를 들어 두 날짜 사이의 간격이 며칠인지, 몇 개월 차이인지 확인할 수 있습니다.
import java.time.LocalDate;
import java.time.Period;
LocalDate start = LocalDate.of(2025, 1, 1);
LocalDate end = LocalDate.now();
Period gap = Period.between(start, end);
System.out.println("차이: " + gap.getYears() + "년 " + gap.getMonths() + "개월 " + gap.getDays() + "일");
날짜 계산 기능은 실무에서도 다양하게 활용됩니다.
정기 구독 갱신일 계산, 멤버십 만료일 안내, 특정 기준일 이전/이후 필터링 등에서도 자주 등장하죠.
기간 차이 계산이 필요한 상황에서는 Period, 시간 단위의 차이는 Duration 클래스를 함께 알아두면 더 유용합니다.
🔤 날짜 포맷 변경과 문자열 변환 방법
날짜 데이터를 화면에 출력하거나 문자열로 저장할 때 가장 중요한 작업 중 하나가 바로 날짜 포맷 변경입니다.
사용자에게 보기 좋은 형태로 보여주기 위해 yyyy-MM-dd, yyyy년 MM월 dd일 같은 형식을 자유롭게 설정할 수 있어야 하죠.
자바 8부터는 DateTimeFormatter 클래스를 활용해 날짜 객체를 문자열로 변환하거나, 그 반대로도 쉽게 처리할 수 있습니다.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
LocalDate date = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일");
String formattedDate = date.format(formatter);
System.out.println("포맷된 날짜: " + formattedDate);
반대로 문자열을 날짜로 파싱하고 싶을 때도 parse() 메서드를 활용하면 됩니다.
String input = "2025년 12월 25일";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일");
LocalDate date = LocalDate.parse(input, formatter);
System.out.println("파싱된 날짜: " + date);
포맷 문자열은 원하는 형식에 맞게 자유롭게 구성할 수 있으며, 다음과 같은 패턴들을 자주 사용합니다.
- 🗓️yyyy-MM-dd → 2025-08-04
- 📆dd/MM/yyyy → 04/08/2025
- 🕐yyyy-MM-dd HH:mm:ss → 2025-08-04 14:00:00
다국어 날짜 처리, 서버 간 시간 포맷 통일 등에서도 포맷 지정은 매우 중요한 역할을 합니다.
개발 초기에 명확한 포맷 정책을 정해두는 것이 버그와 혼란을 줄이는 핵심이 될 수 있어요.
❓ 자바 날짜 관련 자주 묻는 질문 (FAQ)
LocalDate와 Date는 어떤 차이가 있나요?
LocalDateTime은 시간대 정보를 포함하나요?
Calendar는 지금도 사용해도 되나요?
날짜 포맷은 어디에서 지정하나요?
LocalDate는 시간을 설정할 수 없나요?
Period와 Duration의 차이점은 무엇인가요?
문자열을 날짜로 변환할 때 오류가 나요. 이유가 뭔가요?
LocalDate를 JSON으로 직렬화할 때 주의할 점이 있나요?
🧭 LocalDate와 Calendar, 자바 날짜 처리의 기준을 세우다
자바에서 날짜를 처리하는 방식은 시대에 따라 달라져 왔습니다.
예전에는 Calendar와 Date 클래스가 주로 사용됐지만, 복잡한 구조와 낮은 가독성, 스레드 안정성 문제로 인해 많은 불편이 따랐습니다.
Java 8 이후 도입된 java.time 패키지는 이러한 문제를 해결하며, 보다 직관적이고 안전한 API를 제공합니다.
특히 LocalDate, LocalDateTime, DateTimeFormatter 등은 개발자가 날짜와 시간을 다루는 방식을 획기적으로 바꾸어 놓았죠.
이번 글에서는 LocalDate와 Calendar의 기본 구조부터 시작해, 날짜 계산, 포맷 변경, 날짜 간 차이 계산까지 실전 위주로 살펴보았습니다.
불변 객체로서의 안정성과 편리한 메서드 활용, 다양한 포맷 처리까지 가능한 java.time 패키지를 적극적으로 활용해 보세요.
기존 코드가 Calendar 기반이라면 점진적인 마이그레이션도 고려해보는 것이 좋습니다.
날짜 처리 하나만으로도 코드의 품질과 유지보수성이 달라질 수 있습니다.
🏷️ 관련 태그 : java날짜, LocalDate, Calendar, 자바시간계산, DateTimeFormatter, 날짜포맷, 자바8기능, 불변객체, 자바개발팁, 시간차계산