자바

Java 날짜/시간 클래스 완전 정복 (Date, Calendar, LocalDateTime, OffsetDateTime, ZonedDateTime)

a-bell2 2025. 6. 6. 16:08

📦 Java 날짜/시간 클래스 완전 정복 (Date, Calendar, LocalDateTime, OffsetDateTime, ZonedDateTime)

Java에서 날짜와 시간을 다루는 클래스들은 java.util, java.time 패키지에 걸쳐 다양하게 존재합니다. 오래된 클래스부터 최신 클래스까지 개념과 사용법을 정리해두면 프로젝트에서도 헷갈리지 않게 사용할 수 있습니다.


🔹 java.util 패키지: Date & Calendar

🕓 Date 클래스란?

Date는 Java에서 날짜와 시간을 다루기 위한 가장 초기의 클래스입니다. 객체 내부에는 특정 시점을 기준으로 한 연도, 월, 일, 시, 분, 초 등의 정보가 들어갑니다.

📌 데이터베이스 연동 시 날짜를 전달하거나 받아올 때 여전히 많이 쓰입니다.

Date now = new Date();  // 현재 날짜와 시간

📌 주요 기능

기능  설명
getTime() 기준 시점(1970-01-01)부터의 밀리초 값
before(Date) 특정 시간 이전인지 확인
after(Date) 특정 시간 이후인지 확인
compareTo(Date) 날짜 비교 (-1, 0, 1)

⚠️ 참고: 많은 메서드가 현재는 사용 권장되지 않으며, 대체로 Calendar 또는 java.time 계열 클래스가 사용됩니다.


🗓️ Calendar 클래스란?

Calendar는 날짜를 필드 단위로 조작할 수 있게 설계된 추상 클래스입니다. getInstance() 정적 메서드로 인스턴스를 생성하며, 내부적으로 GregorianCalendar 객체를 반환합니다.

Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);

📌 주요 기능

메서드  설명
get(int field) 연도, 월, 일 등 필드 단위 정보 추출
set(int field, int value) 특정 필드 값 설정
add(int field, int amount) 날짜 조작 (더하기/빼기)
getTime() Date로 변환
setTime(Date) Date를 기준으로 설정

📎 주의: Calendar.MONTH는 0부터 시작합니다 (1월 → 0)


🔸 java.time 패키지: Java 8 이상에서 사용

🕐 LocalDateTime

LocalDateTime은 날짜와 시간을 모두 표현하지만, 시간대 정보는 포함하지 않는 순수한 클래스입니다.

LocalDateTime now = LocalDateTime.now();
LocalDateTime dt = LocalDateTime.of(2025, 6, 6, 15, 30);

📌 특징 정리

항목  내용
시간대 ❌ 없음
불변성 ✅ 값 변경 불가, 새 객체 반환
조작 ✅ 더하기/빼기/비교 등 가능
포맷 ✅ DateTimeFormatter 사용
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = now.format(fmt);

🕑 OffsetDateTime

OffsetDateTime은 시간 정보에 UTC 기준 오프셋을 포함한 형태입니다.

OffsetDateTime odt = OffsetDateTime.now(); // 시스템 오프셋 기준
항목  내용
시간대 이름 ❌ 없음
오프셋 포함 ✅ 예 (+09:00 등)
서머타임 고려 ❌ 안함
사용 예 로그, API 응답, DB 저장용 시간

🌍 ZonedDateTime

ZonedDateTime은 가장 많은 정보를 담고 있는 클래스입니다. 시간대 이름오프셋을 모두 포함하며, 서머타임 자동 적용도 지원합니다.

ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Asia/Seoul"));
항목  내용
시간대 ✅ 예 (Asia/Seoul 등)
오프셋 포함 ✅ 예
서머타임 반영 ✅ 가능
사용 예 글로벌 서비스, 항공 예약, 국제 회의 일정

✅ 세 클래스 비교

항목  LocalDateTime  OffsetDateTime  ZonedDateTime
날짜/시간
오프셋
시간대
서머타임
예시 출력 2025-06-06T15:00 2025-06-06T15:00+09:00 2025-06-06T15:00+09:00[Asia/Seoul]

🎯 실무 팁 요약

상황  추천 클래스
단순 시간 기록 (게시물 등록 등) LocalDateTime
DB 저장, API 응답 OffsetDateTime
사용자 지역 시간 반영 ZonedDateTime

💾 저장과 표시 분리 전략

// 저장할 때 (프론트에서 ISO 8601 형식 수신)
OffsetDateTime odt = OffsetDateTime.parse("2025-06-06T06:00:00Z");

// 사용자 화면 표시 시 (시간대 고려)
ZonedDateTime zdt = odt.atZoneSameInstant(ZoneId.of("Asia/Seoul"));
System.out.println("KST 시간 기준: " + zdt);

📌 결론

  • ✅ 저장은 OffsetDateTime으로 깔끔하게 UTC 기준 처리!
  • ✅ 보여줄 때만 ZonedDateTime으로 변환해서 시간대 반영!
  • ❌ 시간대 정보 없이 LocalDateTime만 쓰면 사용자 위치에 따라 시간 오차 발생 위험!

📎 함께 보면 좋은 키워드 요약:

  • Date: 날짜/시간 객체 (구버전)
  • Calendar: 날짜 계산 기능 추가된 구버전
  • LocalDateTime: 시간대 없음, 내부 연산에 적합
  • OffsetDateTime: UTC 기준 오프셋 포함, API/DB에 적합
  • ZonedDateTime: 시간대/서머타임까지 포함, 전 세계 서비스에 적합