[Java] Java에서 날짜와 시간 처리하기

기록하기·2024년 11월 19일

Java

목록 보기
5/9

Java는 초기부터 날짜와 시간을 다루는 다양한 API를 제공해왔다. 하지만 이런 API들은 사용하기에 여러 불편점과 문제점이 있었다. 이런 불편점들을 점차 보완한 뒤 Java 8부터 java.time 패키지가 도입되어 현대적인 날짜와 시간 처리가 가능해졌다 .

1. Java 8 이전의 API들

1.1 Java.util.Date

가장 먼저 등장한 클래스는 java.util.DateJava 1.0부터 도입되었다. 하지만 여러가지 단점이 존재했다.

  • 가변 객체로 설계되어 멀티스레드 환경에서 안전하지 않다.
  • 월(Month)이 0부터 시작하는 비직관적인 설계로 혼란을 유발할 수 있다.
  • 시간대(Time Zone) 처리 기능이 부족하여 글로벌 애플리케이션 개발에 한계가 있다.

1.2 Java.util.Calendar

이러한 문제를 개선하기 위해 Java 1.1부터 도입된 java.util.Calendar 클래스는 다양한 캘린더 시스템을 지원하며, Date 클래스의 단점을 보완하려 했으나 여전히 몇 가지 단점이 남아있었다.

  • 여전히 가변 객체로 설계되어 멀티스레드 환경에서 안전하지 않다.
  • 복잡한 API 설계로 인해 사용하기 어려웠다.

2. Java 8 이후: java.time 패키지

Java 8에서는 이러한 문제를 해결하기 위해 java.time 패키지가 도입다.
이 패키지는 JSR-310 명세를 기반으로 설계되었으며, Modern Date-Time API로 불리며 현재 Java에서 날짜와 시간을 처리하는 표준으로 자리잡았다.

2.1 java.time 패키지의 주요 특징

  1. 불변 객체와 Thread-Safe
    java.time의 모든 클래스는 불변(Immutable) 객체로 설계되어 멀티스레드 환경에서도 안전하게 사용할 수 있다.

  2. 직관적이고 간단한 API
    클래스와 메서드 이름이 직관적이어서 쉽게 이해하고 사용할 수 있다.

    • 예: LocalDate(날짜), LocalTime(시간), LocalDateTime(날짜와 시간), ZonedDateTime(시간대 포함).
  3. 시간대(Time Zone) 지원
    글로벌 애플리케이션 개발에 유용한 시간대 처리 기능을 제공한다. ZoneIdZonedDateTime 클래스를 통해 명확한 시간대 처리가 가능해졌다.

  4. 편리한 날짜와 시간 계산
    plusDays(), minusMonths() 과 같이 직관적인 메서드를 사용해 간단하게 날짜와 시간을 계산할 수 있게 되었다.

  5. 포맷팅과 파싱
    DateTimeFormatter 클래스를 사용하여 날짜와 시간을 간단하고 안전하게 포맷하거나 파싱할 수 있다.

  6. 다양한 목적의 클래스
    특정 목적에 맞는 클래스를 제공하여 더 명확하고 효과적인 코드를 작성할 수 있다.

    • LocalDate: 날짜만 필요할 때
    • LocalTime: 시간만 필요할 때
    • LocalDateTime: 날짜와 시간을 함께 다룰 때
    • Instant: UTC 기준 타임스탬프 표현

2.2 사용 예시

import java.time.*;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        // 현재 날짜와 시간
        LocalDate date = LocalDate.now(); 				// 2024-11-19
        LocalTime time = LocalTime.now(); 				// 21:53:07.250832
        LocalDateTime dateTime = LocalDateTime.now();	// 2024-11-19T21:53:07.250857
		
        // 날짜 계산
        LocalDate nextWeek = date.plusWeeks(1);
        System.out.println("오늘: " + date);			// 오늘: 2024-11-19
        System.out.println("1주 후: " + nextWeek);	// 1주 후: 2024-11-26

        // 포맷팅
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formattedDate = dateTime.format(formatter);
        System.out.println("formattedDate);	// 2024-11-19 21:53:07

        // 시간대 포함
        ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Seoul"));
        System.out.println("zonedDateTime); 
        // 2024-11-19T21:53:07.281712+09:00[Asia/Seoul]
    }
}

2.3 주요 클래스

클래스설명예시 값
LocalDate날짜만 처리 (시간 없음)2024-11-19
LocalTime시간만 처리 (날짜 없음)14:30:15
LocalDateTime날짜와 시간 모두 처리2024-11-19T14:30:15
ZonedDateTime날짜와 시간 + 시간대 정보 포함2024-11-19T14:30:15+09:00[Asia/Seoul]
InstantUTC 기준 타임스탬프 (초/나노초 단위)2024-11-19T05:30:15Z
Duration두 시간 간의 차이 (초/나노초 단위)PT2H30M (2시간 30분)
Period두 날짜 간의 차이 (연도, 월, 일 단위)P1Y2M10D (1년 2개월 10일)

2.4 주요 메서드

// 현재 날짜 및 시간 가져오기
LocalDate.now();        // 현재 날짜
LocalTime.now();        // 현재 시간
LocalDateTime.now();    // 현재 날짜와 시간
ZonedDateTime.now();    // 현재 날짜와 시간 (시간대 포함)

// 날짜 계산
LocalDate today = LocalDate.now();
today.plusDays(5);       // 5일 추가
today.minusMonths(1);    // 1개월 빼기

// 비교
LocalDate date1 = LocalDate.of(2023, 1, 1);
LocalDate date2 = LocalDate.of(2024, 1, 1);
boolean isBefore = date1.isBefore(date2); // true
boolean isAfter = date1.isAfter(date2);   // false

// 포맷팅
LocalDate date = LocalDate.now();
String formatted = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

// 파싱
LocalDate parsedDate = LocalDate.parse("2024-01-01", DateTimeFormatter.ofPattern("yyyy-MM-dd"));

0개의 댓글