1. LocalDate: 시간과 시간대가 없는 날짜
LocalDate는 그 자체로 “날짜”입니다. 시간도, 시간대도 없습니다. 달력의 한 페이지처럼: 2025-06-01 — 그게 전부입니다. 도시마다 정확히 언제 “자정”이 되는지가 중요하지 않고 그냥 “2025년 6월 1일”만 필요하다면 LocalDate를 사용하세요.
LocalDate를 어떻게 만들까요?
방법은 몇 가지가 있으며 모두 간단하고 편리합니다.
현재 날짜
import java.time.LocalDate;
LocalDate today = LocalDate.now();
System.out.println(today); // 예: 2025-06-01
구체적인 날짜
LocalDate birthday = LocalDate.of(1990, 12, 15);
System.out.println(birthday); // 1990-12-15
연, 월, 일을 숫자로 사용할 수 있습니다. 월은 1부터 12까지의 숫자입니다(1월 — 1, 12월 — 12).
문자열에서 파싱
LocalDate parsedDate = LocalDate.parse("2025-06-01");
System.out.println(parsedDate); // 2025-06-01
문자열은 yyyy-MM-dd 형식이어야 합니다. 형식이 일치하지 않으면 예외가 발생합니다.
날짜 구성 요소 가져오기
LocalDate에는 날짜의 개별 부분을 반환하는 메서드가 있습니다:
int year = today.getYear(); // 2025
int month = today.getMonthValue(); // 6 (6월)
int day = today.getDayOfMonth(); // 1
System.out.println("연도: " + year + ", 월: " + month + ", 일: " + day);
월 이름을 알고 싶다면 getMonth() 메서드를 사용하세요:
System.out.println(today.getMonth()); // JUNE
요일이 필요하면 getDayOfWeek() 메서드를 사용하세요:
System.out.println(today.getDayOfWeek()); // SATURDAY
실전 예제
학습용 콘솔 애플리케이션을 확장해 봅시다: 이제 사용자에게 생일을 알려줄 수 있습니다.
import java.time.LocalDate;
public class BirthdayApp {
public static void main(String[] args) {
LocalDate birthday = LocalDate.of(2000, 2, 29);
System.out.println("생년월일: " + birthday);
System.out.println("태어난 요일: " + birthday.getDayOfWeek());
}
}
2. LocalTime: 날짜와 시간대가 없는 시간
LocalTime은 그냥 “시간”입니다. 시, 분, 초(그리고 나노초까지). 하지만 날짜는 없습니다! 예를 들어 “가게 오픈 시간”이나 “회의 시작 시간”처럼 날짜와 무관하게 시간을 저장해야 할 때 사용하는 클래스입니다.
LocalTime을 어떻게 만들까요?
현재 시간
import java.time.LocalTime;
LocalTime now = LocalTime.now();
System.out.println(now); // 예: 14:37:12.123456789
구체적인 시간
LocalTime lunchTime = LocalTime.of(13, 30); // 13:30:00
System.out.println(lunchTime);
초와 나노초를 추가할 수 있습니다:
LocalTime precise = LocalTime.of(8, 15, 30, 123_000_000); // 08:15:30.123
System.out.println(precise);
문자열에서 파싱
LocalTime parsedTime = LocalTime.parse("14:30:00");
System.out.println(parsedTime); // 14:30
시간 구성 요소 가져오기
int hour = now.getHour();
int minute = now.getMinute();
int second = now.getSecond();
System.out.println("시: " + hour + ", 분: " + minute + ", 초: " + second);
실전 예제
우리 앱에 “시계”를 추가해 봅시다:
import java.time.LocalTime;
public class ClockApp {
public static void main(String[] args) {
LocalTime current = LocalTime.now();
System.out.println("현재: " + current);
System.out.println("시: " + current.getHour());
System.out.println("분: " + current.getMinute());
}
}
3. LocalDateTime: 시간대가 없는 날짜와 시간
LocalDateTime은 콤보입니다: 날짜 + 시간, 하지만 여전히 시간대는 없습니다. 예: “2025-06-01 14:30:00”. 특정 순간을 저장하되, 어디에서 읽히는지는 신경 쓰지 않을 때 유용합니다.
LocalDateTime을 어떻게 만들까요?
현재 날짜와 시간
import java.time.LocalDateTime;
LocalDateTime now = LocalDateTime.now();
System.out.println(now); // 예: 2025-06-01T14:30:15.123456789
구체적인 날짜와 시간
LocalDateTime meeting = LocalDateTime.of(2025, 6, 1, 14, 30);
System.out.println(meeting); // 2025-06-01T14:30
초와 나노초를 추가할 수 있습니다:
LocalDateTime preciseMeeting = LocalDateTime.of(2025, 6, 1, 14, 30, 45, 123_000_000);
System.out.println(preciseMeeting); // 2025-06-01T14:30:45.123
문자열에서 파싱
LocalDateTime parsed = LocalDateTime.parse("2025-06-01T14:30:00");
System.out.println(parsed); // 2025-06-01T14:30
주의: 표준 ISO에 따라 문자 T가 날짜와 시간을 구분합니다.
구성 요소 가져오기
int year = now.getYear();
int month = now.getMonthValue();
int day = now.getDayOfMonth();
int hour = now.getHour();
int minute = now.getMinute();
System.out.println("날짜: " + year + "-" + month + "-" + day + " 시간: " + hour + ":" + minute);
4. 날짜와 시간의 일반적인 연산
이제 날짜와 시간 객체를 만들 수 있으니, 그것들로 유용한 작업을 해 봅시다.
더하기와 빼기
세 클래스(LocalDate, LocalTime, LocalDateTime)는 모두 불변입니다. 즉, plusDays()나 minusMonths() 같은 메서드는 새로운 객체를 반환하며, 기존 객체는 변경되지 않습니다.
LocalDate
LocalDate today = LocalDate.now();
LocalDate tomorrow = today.plusDays(1);
LocalDate lastMonth = today.minusMonths(1);
System.out.println("오늘: " + today);
System.out.println("내일: " + tomorrow);
System.out.println("한 달 전: " + lastMonth);
LocalTime
LocalTime now = LocalTime.now();
LocalTime inTenMinutes = now.plusMinutes(10);
System.out.println("현재: " + now);
System.out.println("10분 후: " + inTenMinutes);
LocalDateTime
LocalDateTime start = LocalDateTime.of(2025, 6, 1, 14, 0);
LocalDateTime end = start.plusHours(2).minusMinutes(15);
System.out.println("시작: " + start);
System.out.println("종료: " + end);
날짜와 시간 비교
모든 클래스에는 isBefore(), isAfter(), isEqual() 메서드가 있습니다:
LocalDate birthday = LocalDate.of(2000, 2, 29);
LocalDate today = LocalDate.now();
if (today.isAfter(birthday)) {
System.out.println("당신은 방금 태어난 것보다 나이가 많습니다!");
}
LocalTime morning = LocalTime.of(8, 0);
LocalTime now = LocalTime.now();
if (now.isBefore(morning)) {
System.out.println("아직 일어나기 이릅니다...");
} else {
System.out.println("일어날 시간입니다!");
}
현재 날짜/시간 가져오기
보셨듯이 now() 메서드는 현재 값을 반환합니다:
LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime dateTime = LocalDateTime.now();
5. 실습: 예제와 과제
예제 1: 임의의 날짜의 요일
import java.time.LocalDate;
public class DayOfWeekApp {
public static void main(String[] args) {
LocalDate anyDate = LocalDate.of(2025, 12, 31);
System.out.println("2025년 12월 31일 — " + anyDate.getDayOfWeek());
}
}
예제 2: 새해까지 며칠 남았을까?
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
public class DaysToNewYear {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
LocalDate newYear = LocalDate.of(today.getYear() + 1, 1, 1);
long daysLeft = ChronoUnit.DAYS.between(today, newYear);
System.out.println("새해까지 " + daysLeft + "일 남았습니다!");
}
}
예제 3: 윤년인지 확인
import java.time.LocalDate;
public class LeapYearCheck {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2025, 1, 1);
if (date.isLeapYear()) {
System.out.println(date.getYear() + " — 윤년입니다!");
} else {
System.out.println(date.getYear() + " — 평년입니다.");
}
}
}
예제 4: 두 시간 사이의 차이
import java.time.LocalTime;
import java.time.Duration;
public class TimeDifference {
public static void main(String[] args) {
LocalTime start = LocalTime.of(9, 0);
LocalTime end = LocalTime.of(17, 30);
Duration duration = Duration.between(start, end);
System.out.println("근무 시간은 " + duration.toHours() + "시간 " +
(duration.toMinutes() % 60) + "분입니다.");
}
}
6. 자주 하는 실수
실수 №1: LocalDateTime과 ZonedDateTime을 혼동함.
LocalDateTime에는 시간대 정보가 없습니다! 국가 간 항공편 일정이나 서로 다른 시간대에서 발생하는 이벤트를 저장한다면 — ZonedDateTime을 사용하세요. 그렇지 않으면 시스템 간 데이터 이전 시 예상치 못한 결과가 나올 수 있습니다.
실수 №2: 파싱에 잘못된 문자열 형식을 사용함.
예를 들어 01.06.2025를 LocalDate.parse()로 파싱하려고 시도합니다. 기본적으로는 2025-06-01 형식을 기대합니다. 다른 형식에는 전용 DateTimeFormatter가 필요합니다(이는 다음 강의에서 다룹니다!).
실수 №3: plusDays() 같은 메서드가 객체를 변경한다고 생각함.
아닙니다! 모든 객체는 불변입니다. 메서드는 새 객체를 반환하고, 기존 객체는 그대로 유지됩니다.
실수 №4: 절대 시간을 저장하는 데 LocalTime을 사용함.
LocalTime은 하루 중 “로컬 시간”만을 위한 것입니다. “어떤 순간”을 보존하려면 Instant나 ZonedDateTime을 사용하세요.
실수 №5: 월 번호를 혼동함(1 — 1월, 12 — 12월).
LocalDate.of(year, month, day)에서 월은 1부터 시작합니다(일부 다른 언어나 오래된 API처럼 0부터가 아닙니다).
GO TO FULL VERSION