← Java 강의 목록으로
모던 자바
모던 자바 · 선수: 이전 단원

20. Date · Time

날짜·시간을 다루는 표준 API 는 JDK 8 부터 `java.time` 패키지로 대대적으로 개편되었습니다. 불변 객체, 명확한 의미, 시간대 처리까지 갖춰 이전의 `Date`/`Calendar` 보다 압도적으로 사용하기 쉽습니다.

Java모던함수형Date · Time
소요 시간
약 1.5~2시간
난이도
📊 중급-고급
선수 조건
🎯 이전 단원 또는 동등 지식
결과물
날짜·시간을 다루는 표준 API 는 JDK 8 부터 `java.time` 패키지로 대대적으로 개편되었습니다. 불변 객체, 명확한 의미, 시간대 처리까지 갖춰 이전의 `Date`/`Calendar` 보다 압도적으로 사용하기 쉽습니다.

이 강의에서 배우는 것

  • 1`LocalDate`, `LocalTime`, `LocalDateTime`, `ZonedDateTime` 의 차이를 안다
  • 2날짜 산술(`plusDays` / `minusMonths` 등) 을 사용한다
  • 3`DateTimeFormatter` 로 파싱·포맷팅한다
  • 4`Duration` 과 `Period` 로 시간/기간을 표현한다

소개

날짜·시간을 다루는 표준 API 는 JDK 8 부터 `java.time` 패키지로 대대적으로 개편되었습니다. 불변 객체, 명확한 의미, 시간대 처리까지 갖춰 이전의 `Date`/`Calendar` 보다 압도적으로 사용하기 쉽습니다.

핵심 개념

1) 4 가지 타입

타입표현
`LocalDate`날짜2026-05-16
`LocalTime`시각09:30
`LocalDateTime`날짜+시각2026-05-16T09:30
`ZonedDateTime`위 + 시간대2026-05-16T09:30+09:00[Asia/Seoul]

2) 생성

java
LocalDate today = LocalDate.now();
LocalDate xmas = LocalDate.of(2026, 12, 25);
LocalDateTime dt = LocalDateTime.now();
ZonedDateTime seoul = ZonedDateTime.now(ZoneId.of("Asia/Seoul"));

3) 산술

java
LocalDate tomorrow = today.plusDays(1);
LocalDate lastWeek = today.minusWeeks(1);
boolean before = today.isBefore(xmas);

`java.time` 객체는 모두 **불변** — 메서드는 새 인스턴스를 반환합니다.

4) 포맷팅

java
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm");
String s = LocalDateTime.now().format(fmt);
LocalDate parsed = LocalDate.parse("2026-05-16");

5) `Duration` vs `Period`

클래스단위용도
`Duration`초·나노초시각 간 간격
`Period`년·월·일날짜 간 간격

핵심 예제

예제 1 — `DateBasics.java` : 생성과 산술

java
import java.time.LocalDate;

public class DateBasics {
    public static void main(String[] args) {
        LocalDate today = LocalDate.of(2026, 5, 16);
        LocalDate xmas = LocalDate.of(2026, 12, 25);
        System.out.println("오늘: " + today);
        System.out.println("크리스마스: " + xmas);
        System.out.println("내일: " + today.plusDays(1));
        System.out.println("한 달 전: " + today.minusMonths(1));
        System.out.println("크리스마스 전? " + today.isBefore(xmas));
    }
}

**실행 결과**

text
오늘: 2026-05-16
크리스마스: 2026-12-25
내일: 2026-05-17
한 달 전: 2026-04-16
크리스마스 전? true

**메모:** ISO-8601 (`yyyy-MM-dd`) 가 기본 표현입니다.

예제 2 — `TimeBasics.java` : 시각과 시간대

java
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class TimeBasics {
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(2026, 5, 16, 9, 30);
        System.out.println("로컬: " + ldt);

        ZonedDateTime seoul = ldt.atZone(ZoneId.of("Asia/Seoul"));
        ZonedDateTime ny = seoul.withZoneSameInstant(ZoneId.of("America/New_York"));
        System.out.println("서울: " + seoul);
        System.out.println("뉴욕: " + ny);
    }
}

**실행 결과**

text
로컬: 2026-05-16T09:30
서울: 2026-05-16T09:30+09:00[Asia/Seoul]
뉴욕: 2026-05-15T20:30-04:00[America/New_York]

**메모:** `withZoneSameInstant` 는 **같은 순간** 을 다른 시간대 표현으로 바꿉니다.

예제 3 — `Formatter.java` : 포맷·파싱

java
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class Formatter {
    public static void main(String[] args) {
        LocalDateTime dt = LocalDateTime.of(2026, 5, 16, 9, 30, 45);
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss");
        System.out.println(dt.format(fmt));

        LocalDateTime parsed = LocalDateTime.parse("2026-05-16T09:30:45");
        System.out.println(parsed);
    }
}

**실행 결과**

text
2026.05.16 09:30:45
2026-05-16T09:30:45

**메모:** ISO 표준 형식은 별도 포매터 없이 `parse` 됩니다.

예제 4 — `DurationAndPeriod.java` : 기간 계산

java
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Period;

public class DurationAndPeriod {
    public static void main(String[] args) {
        LocalTime a = LocalTime.of(9, 0);
        LocalTime b = LocalTime.of(17, 30);
        Duration work = Duration.between(a, b);
        System.out.println("근무 분: " + work.toMinutes());

        LocalDate birth = LocalDate.of(2005, 3, 1);
        LocalDate now = LocalDate.of(2026, 5, 16);
        Period age = Period.between(birth, now);
        System.out.printf("나이: %d년 %d개월 %d일%n",
            age.getYears(), age.getMonths(), age.getDays());
    }
}

**실행 결과**

text
근무 분: 510
나이: 21년 2개월 15일

**메모:** 시간 간격은 `Duration`, 날짜 간격은 `Period` 를 사용하세요.

전체 예제 코드 (src/)

src/DateBasics.java

java
import java.time.LocalDate;

public class DateBasics {
    public static void main(String[] args) {
        LocalDate today = LocalDate.of(2026, 5, 16);
        LocalDate xmas = LocalDate.of(2026, 12, 25);
        System.out.println("오늘: " + today);
        System.out.println("크리스마스: " + xmas);
        System.out.println("내일: " + today.plusDays(1));
        System.out.println("한 달 전: " + today.minusMonths(1));
        System.out.println("크리스마스 전? " + today.isBefore(xmas));
    }
}

src/DurationAndPeriod.java

java
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Period;

public class DurationAndPeriod {
    public static void main(String[] args) {
        LocalTime a = LocalTime.of(9, 0);
        LocalTime b = LocalTime.of(17, 30);
        Duration work = Duration.between(a, b);
        System.out.println("근무 분: " + work.toMinutes());

        LocalDate birth = LocalDate.of(2005, 3, 1);
        LocalDate now = LocalDate.of(2026, 5, 16);
        Period age = Period.between(birth, now);
        System.out.printf("나이: %d년 %d개월 %d일%n",
            age.getYears(), age.getMonths(), age.getDays());
    }
}

src/Formatter.java

java
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class Formatter {
    public static void main(String[] args) {
        LocalDateTime dt = LocalDateTime.of(2026, 5, 16, 9, 30, 45);
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss");
        System.out.println(dt.format(fmt));

        LocalDateTime parsed = LocalDateTime.parse("2026-05-16T09:30:45");
        System.out.println(parsed);
    }
}

src/TimeBasics.java

java
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class TimeBasics {
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.of(2026, 5, 16, 9, 30);
        System.out.println("로컬: " + ldt);

        ZonedDateTime seoul = ldt.atZone(ZoneId.of("Asia/Seoul"));
        ZonedDateTime ny = seoul.withZoneSameInstant(ZoneId.of("America/New_York"));
        System.out.println("서울: " + seoul);
        System.out.println("뉴욕: " + ny);
    }
}

자주 하는 실수

  1. 옛 `java.util.Date` / `Calendar` 사용 (비권장)
  2. `Duration` 으로 날짜 간격, `Period` 로 시간 간격을 다루려 함 (역할 반대)
  3. 시간대 누락한 채 서로 다른 지역 시간 비교
  4. 객체가 불변이라 `today.plusDays(1)` 만 호출하고 결과를 안 받음 → 의미 없음
  5. 로컬 시간을 그대로 DB 저장 → 다른 지역 사용자에게는 다른 시점이 됨

정리

  • `java.time` 은 불변·명확·풍부한 모던 API
  • 4가지 핵심 타입을 상황에 맞게 골라 사용
  • 포맷팅은 `DateTimeFormatter` 로
  • 기간은 `Duration` / `Period` 둘로 명확히 구분

과제

# 과제 - 20. Date · Time

## 문제 1 — 오늘부터 D-Day 계산

  • 파일명: `Homework01.java`
  • 핵심 개념: `LocalDate`, `Period`, `Duration`

요구사항

  • 기준일 2026-05-16, 목표일 2026-12-25 (성탄절).
  • 두 날짜의 차이를 `Period.between` 으로 "X일" 형식으로 출력.

예상 출력

text
D-223일

힌트

  • `ChronoUnit.DAYS.between(a, b)` 가 가장 직관적입니다.

## 문제 2 — 출근 포맷

  • 파일명: `Homework02.java`
  • 핵심 개념: `LocalDateTime`, `DateTimeFormatter`

요구사항

  • 시각 `2026-05-16 09:00` 을 만들어 다음 두 형식으로 출력.
  • 형식 A: `yyyy년 M월 d일 a h시 m분` (예: `2026년 5월 16일 오전 9시 0분`)
  • 형식 B: `yyyy-MM-dd HH:mm`

예상 출력

text
2026년 5월 16일 오전 9시 0분
2026-05-16 09:00

## 정답 확인 직접 풀어 본 후 [`answer/`](./answer/) 폴더의 정답과 비교해 보세요.

정답 코드 (homework/answer/)

answer/Homework01.java

java
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

/** D-Day 계산. */
public class Homework01 {
    public static void main(String[] args) {
        LocalDate base = LocalDate.of(2026, 5, 16);
        LocalDate target = LocalDate.of(2026, 12, 25);
        long days = ChronoUnit.DAYS.between(base, target);
        System.out.println("D-" + days + "일");
    }
}

answer/Homework02.java

java
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

/** 출근 시각 두 가지 포맷. */
public class Homework02 {
    public static void main(String[] args) {
        LocalDateTime dt = LocalDateTime.of(2026, 5, 16, 9, 0);
        DateTimeFormatter a = DateTimeFormatter.ofPattern("yyyy년 M월 d일 a h시 m분", Locale.KOREAN);
        DateTimeFormatter b = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        System.out.println(dt.format(a));
        System.out.println(dt.format(b));
    }
}

직접 해 보기

bash
cd 05_모던_자바/20_Date_Time/src
javac DateBasics.java
java DateBasics

다음 단원

[21_Maven_Gradle](../21_Maven_Gradle/) — 빌드 도구로 본격 프로젝트 구조를 익힙니다.

예제 코드 / 강의 자료

전체 강의 자료와 예제 코드는 GitHub에서 자유롭게 받아볼 수 있습니다.

GitHub에서 보기 ↗