콘텐츠로 건너뛰기

자바에서 날짜와 시간 다루기

  • 테크

날짜와 시간을 다루는 것은 많은 프로그램에서 매우 중요한 요소 중 하나입니다. 사용자의 가입 날짜를 저장하거나, 예약 시스템을 구현하는 등 다양한 상황에서 날짜와 시간 데이터를 다루게 되는데요, 이러한 데이터들은 단순한 숫자가 아니기 때문에 시간대, 포맷, 연산 등 여러 가지 요소를 고려하여 처리해야 합니다.

자바에서는 오래전부터 Date와 Calendar 클래스를 제공하여 날짜와 시간을 처리할 수 있도록 했지만, 이들은 설계상의 단점이 많아 사용이 불편했습니다. 이를 해결하기 위해 Java 8부터 새로운 날짜·시간 API(java.time 패키지)가 도입되었으며, 더 직관적이고 안전하게 날짜와 시간을 다룰 수 있게 되었습니다.

이번 포스팅에서는 기존의 Date와 Calendar 클래스를 먼저 간단히 살펴본 후 Java 8 이후부터 제공되는 java.time 패키지의 날짜 및 시간 관련 클래스에 대해 정리해보겠습니다. 

Date와 Calendar

Date 클래스 (java.util.Date)

Date 클래스는 Java에서 날짜와 시간을 표현하는 대표적인 클래스로, JDK 1.0부터 제공되었습니다.

📝 예시 코드
import java.util.Date;

public class Main {
  public static void main(String[] args) {
    Date date = new Date();
    System.out.println("date : " + now);
  }
}
date : Wed Feb 19 08:20:59 KST 2025
Date 클래스의 문제점

하지만 Date 클래스는 다음과 같은 문제점들을 가졌으며, 이러한 문제들은 이후 Calendar, java.time 패키지 등 새로운 API가 도입되는 계기가 되었습니다.

변경 가능한 객체
Date 객체는 불변 객체가 아니기 때문에 수정이 가능합니다. 만약 Date 객체 하나가 멀티 스레드(여러 개의 작업) 환경에서 공유된다면 데이터의 안전성을 보장할 수 없습니다.

시간대(TimeZone) 개념이 없음
Date 객체는 자체적으로 UTC(협정 세계시) 기준의 시간을 저장하지만, 특정 시간대를 직접 지정할 수 있는 기능이 없습니다. 시간대를 다루기 위해서는 Calendar 또는 TimeZone 클래스를 별도로 사용해야하는 불편함이 있습니다.

많은 메서드들이 Deprecated 됨
Date 클래스에는 getYear(), getMonth()와 같이 더 이상 사용을 권장하지 않는 메서드들이 많습니다.

날짜 형식 지정이 어려움
Date 자체로는 날짜 포맷을 지정할 수 없으며, SimpleDateFormat과 함께 사용해야 합니다.

Calendar 클래스 (java.util.Calendar)

Calendar 클래스는 Date 클래스의 단점을 보완하기 위해 JDK 1.1에서 추가된 클래스입니다.

📝 예시 코드
import java.util.Calendar;

public class Main {
  public static void main(String[] args) {
    Calendar calendar = Calendar.getInstance();
    System.out.println("calendar : " + calendar.getTime());
  }
}
calendar : Wed Feb 19 08:37:14 KST 2025
Calendar 클래스의 문제점

Calendar 클래스는 Date 클래스로부터 개선되어 날짜 연산, 시간대(TimeZone) 지원 등의 기능을 제공합니다. 하지만 여전히 불편하고 복잡한 특징을 가지고 있어 사용이 권장되지 않습니다.

여전히 변경 가능한 객체
Calendar 객체 또한 Date 객체처럼 수정이 가능합니다. Calendar 객체를 생성한 후 set()을 통해 값을 변경할 수 있기 때문에 멀티 스레드 환경에서 안전하지 않습니다.

직관적이지 않은 표현 방식 : 월(Month) 인덱스가 0부터 시작
Calendar 클래스에서 월(Month)는 0부터 시작하여 11까지 표현됩니다. 1월은 0, 12월은 11로 다루어지므로 개발자에게 혼란을 초래할 수 있습니다.

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.MONTH, 0); // 1월을 의미함


복잡하고 가독성이 떨어지는 코드
예를 들어, Calendar 클래스에서 날짜를 설정할 때 다음과 같이 여러 줄의 코드를 작성해야 합니다. 이런 방식은 코드가 길고 복잡해져 가독성이 떨어지고, 사용에 불편함이 있습니다.

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, 2025);
calendar.set(Calendar.MONTH, 1);
calendar.set(Calendar.DAY_OF_MONTH, 19);

java.time 패키지

java.time 패키지는 Java 8에서 도입된 새로운 날짜 및 시간 API로, 기존 날짜 및 시간 관련 클래스들의 단점을 보완하며 보다 체계적이고 편리한 기능을 제공합니다.

java.time 패키지의 장점

불변성과 스레드 안전성
java.time 패키지의 모든 클래스는 불변 객체로 설계되어 있기 때문에, 값을 변경할 수 없으며 여러 스레드에서 동시에 사용해도 안전(Thread-safe)합니다.

가독성과 사용성이 향상됨
java.time 패키지는 직관적인 메서드를 제공하여 가독성이 뛰어납니다. 위에서 설명한 Calendar 객체의 날짜 설정 코드는 LocalDate를 활용하면 한 줄로 간결하게 표현할 수 있습니다. 또한, 날짜 연산도 plusDays(), minusMonths(), withYear() 등의 메서드를 사용하여 쉽게 구현할 수 있으며, 메서드의 이름만으로도 수행하는 연산을 이해할 수 있습니다.

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, 2025);
calendar.set(Calendar.MONTH, 1);
calendar.set(Calendar.DAY_OF_MONTH, 19);

=> LocalDate date = LocalDate.of(2025, 2, 19);
LocalDate date = LocalDate.of(2025, 2, 19);  // 2025년 2월 19일 생성
LocalDate newDate = date.plusDays(10);       // 10일 후 날짜 계산 (2025-03-01)
LocalDate updatedYear = date.withYear(2030); // 연도를 2030년으로 변경 (2030-02-19)


명확한 객체 개념 분리
기존에는 Date 객체 하나로 날짜와 시간을 모두 관리해야 했지만, java.time 패키지는 각 개념을 명확하게 분리하여 제공하므로 더 유용합니다.

  • LocalDate : 날짜(년, 월, 일)만 포함
  • LocalTime : 시간(시, 분, 초)만 포함
  • LocalDateTime : 날짜 + 시간 정보 포함
LocalDate today = LocalDate.now();              // 2025-02-19
LocalTime now = LocalTime.now();                // 14:30:00
LocalDateTime dateTime = LocalDateTime.now();   // 2025-02-19T14:30:00


시간대(Time Zone) 및 UTC 처리 기능 향상
java.time 패키지는 ZoneId, ZonedDateTime, OffsetDateTime 등을 통해 다양한 시간대 변환을 쉽게 수행할 수 있습니다.

ZonedDateTime seoulTime = ZonedDateTime.now(ZoneId.of("Asia/Seoul"));
// seoulTime : 2025-02-19T14:55:25.295782700+09:00[Asia/Seoul]


날짜 및 시간 ↔ 문자열 변환 간편화
DateTimeFormatter를 활용하여 날짜와 시간을 손쉽게 문자열로 변환(Formatting)하거나, 문자열을 날짜·시간으로 변환(Parsing)할 수 있습니다.

// 날짜·시간 → 문자열
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = now.format(formatter); 
// formattedDateTime : "2025-02-19 14:30:45"
// 문자열 → 날짜·시간
String dateTimeString = "2025-02-19 14:30:45";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime parsedDateTime = LocalDateTime.parse(dateTimeString, formatter); 
// parsedDateTime : 2025-02-19T14:30:45

다음으로 java.time 패키지의 주요 클래스인 LocalDate, LocalTime, LocalDateTime 에 대해 간단히 알아보도록 하겠습니다. java.time 패키지에 대한 더 많은 정보와 자세한 내용은 공식 문서를 통해 확인하실 수 있습니다🧐

LocalDate 클래스 (java.time.LocalDate)

LocalDate 클래스는 날짜(년, 월, 일)를 표현하는 클래스입니다.

📝 예시 코드
import java.time.LocalDate;

public class Main {
  public static void main(String[] args) {
    LocalDate today = LocalDate.now(); // 오늘 날짜
    System.out.println("today : " + today);

    LocalDate tmpDate = LocalDate.of(2025, 1, 25); // 임의의 날짜 객체 생성
    System.out.println("tmpDate : " + tmpDate);

  }
}
today : 2025-02-19
tmpDate : 2025-01-25

LocalTime 클래스 (java.time.LocalTime)

LocalTime 클래스는 시간(시, 분, 초, 나노초) 정보를 표현하는 클래스입니다.

📝 예시 코드
import java.time.LocalTime;

public class Main {
  public static void main(String[] args) {
      LocalTime now = LocalTime.now(); // 현재 시간
      System.out.println("now : " + now);

      LocalTime newTime = now.plusHours(2).plusMinutes(15); // 현재 시간 + 2시간 15분
      System.out.println("newTime : " + newTime);

      LocalTime tmpTime = LocalTime.of(10, 30, 45, 12345); // 임의의 시간 객체 생성
      System.out.println("tmpTime : " + tmpTime);
  }
}  
now : 14:45:30.123456789
newTime : 17:00:30.123456789
tmpTime : 10:30:45.000012345

LocalDateTime 클래스 (java.time.LocalDateTime)

LocalDateTime 클래스는 날짜(LocalDate)와 시간(LocalTime)을 함께 표현할 수 있는 클래스입니다.

📝 예시 코드
import java.time.LocalDateTime;

public class Main {
  public static void main(String[] args) {
    LocalDateTime now = LocalDateTime.now(); // 현재 날짜·시간
    System.out.println("now : " + now);

    LocalDateTime updatedDateTime = now.plusWeeks(1).plusHours(3); // 현재 날짜·시간 + 1주일 + 3시간
    System.out.println("updatedDateTime : " + updatedDateTime);

    LocalDateTime tmpDateTime = LocalDateTime.of(2025, 1, 25, 10, 30, 30, 12345); // 임의의 날짜·시간 객체 생성
    System.out.println("tmpDateTime : " + tmpDateTime);
  }
}
now : 2025-02-19T14:45:30.123456789
updatedDateTime : 2025-02-26T17:45:30.123456789
tmpDateTime : 2025-01-25T10:30:30.000012345

지금까지 자바에서 날짜와 시간을 다루는 방법에 대해 알아보았습니다.

자바의 날짜·시간 관련 API는 과거 java.util.Date 와 java.util.Calendar에서 시작하여 java.time 패키지로 발전해 왔습니다. 이러한 개선 덕분에 개발자는 보다 안정적이고 효율적인 방식으로 날짜와 시간을 처리할 수 있게 되었습니다.

Date와 Calendar는 여전히 레거시로 존재하는 경우도 많기 때문에, 이에 대한 이해와 함께 java.time 패키지의 다양한 기능을 이용한다면 더 효율적이고 가독성 높은 코드를 작성할 수 있을 것입니다.

이번 포스팅이 자바의 날짜 및 시간 처리 방법을 이해하는 데 도움이 되었길 바라며, 여기에서 마치도록 하겠습니다!


최신 마케팅/고객 데이터 활용 사례를 받아보실 수 있습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다