프로그래밍/Java

Date와 Time API

개발정리 2022. 5. 5. 17:15

기존에 사용하던 날짜와 시간 Api 는 아래와같다. 

Date date = new Date();
Calendar calendar = new Gregoriancalendar();
SimpleDateFormat dateFormat = new SimpleDateFormat();

 

 

Java8 에 새로운 날짜와 시간 API 가 생긴 이유

  • 그 전까지 사용하던 java.util.Date 클래스는 mutable 하기 때문에 thread safe 하지 않다. 
    • .setTime( ) 시 변경이 가능하며, 멀티 쓰레드 환경에서 안전하게 쓰기 어렵다. 
  • 클래스 이름이 명확하지 않다. Date 인데 시간까지 다룬다.
  • 버그 발생할 여지가 많다.
    • 타입 안정성이 없고, 월이 0부터 시작한다거나 등
  • 날짜 시간 처리가 복잡한 애플리케이션에서는 보통 Joda time 을 쓰곤 했다.
    • Joda time? java8 이전에 자주 사용하던 시관 & 날짜 관련 라이브러리

 

 

주요 API

  • 기계용 시간 (machine time) 과 인류용 시간 (human time)으로 나눌 수 있다.
  • 기게용 시간은 EPOCK (1970년 1월 1일 0시 0분 0초)부터 현재까지의 타임스탬프를 표현한다.
  • 인류용 시간은 우리가 흔히 사용하는 연, 월, 일, 시, 분, 초 등을 표현한다.
  • 타임스탬프는 Instant를 사용한다.
  • 특정 날짜(LocalDate), 시간(LocalTime), 일시(LocalDateTime)를 사용할 수 있다.
  • 기간을 표현할 때는 Duration (시간 기반)과 Period (날짜 기반) 을 사용할 수 있다.
  • DateTimeFormatter 를 사용해서 일시를 특정한 문자열로 포매팅할 수 있다.

 

실습

package com.study.java8to11;

import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

public class DateStudy {

  public static void main(String[] args) {
    // 1. [기계용 시간] 지금 이 순간을 기계 시간으로 표현하는 방법
    // Universal Time Coordinated == Greenwich Mean Time
    Instant instant = Instant.now();
    System.out.println(instant); // 기준시 UTC, GMT
    System.out.println(instant.atZone(ZoneId.of("UTC")));

    ZoneId zone = ZoneId.systemDefault();
    System.out.println(zone); // Asia/Seoul

    ZonedDateTime zonedDateTime = instant.atZone(zone);
    System.out.println(zonedDateTime); // 2022-05-05T17:52:39.218033+09:00[Asia/Seoul]

    // 2. [인류용 시간]
    LocalDateTime now = LocalDateTime.now();
    System.out.println(now); // 2022-05-05T17:52:39.234404
    LocalDateTime birthDay = LocalDateTime.of(1992, Month.APRIL, 19, 0, 0, 0);
    System.out.println(birthDay);

    // 특정 Zone 의 특정 일시를 리턴 [방법 1]
    ZonedDateTime nowInKorea = ZonedDateTime.now(ZoneId.of("Asia/Seoul"));
    System.out.println(nowInKorea);

    // 특정 Zone 의 특정 일시를 리턴 [방법 2]
    Instant nowInstant = Instant.now();
    ZonedDateTime zonedDateTime2 = nowInstant.atZone(ZoneId.of("Asia/Seoul"));
    System.out.println(zonedDateTime2);

    // 3. 기간을 표현하는 방법
    LocalDate today = LocalDate.now();
    LocalDate thisYearBirthday = LocalDate.of(2022, Month.JULY, 15);
    // 일 수 차이 확인 [방법 1]
    Period period = Period.between(today, thisYearBirthday);
    System.out.println(period.getDays());
    // 일 수 차이 확인 [방법 2]
    Period until = today.until(thisYearBirthday);
    System.out.println(until.get(ChronoUnit.DAYS));

    // Period 는 인류용 시간 비교, Duration 은 기계용 시간비교
    Instant now2 = Instant.now();
    Instant plus = now2.plus(10, ChronoUnit.SECONDS);
    Duration between = Duration.between(now2, plus);
    System.out.println(between.getSeconds());


    // 4. 파싱 또는 포매팅
    // 포매팅
    LocalDateTime now3 = LocalDateTime.now();
    DateTimeFormatter MMddyyyy = DateTimeFormatter.ofPattern("MM/dd/yyyy");
    System.out.println(now3.format(MMddyyyy));

    // 파싱
    LocalDate parse = LocalDate.parse("04/19/1992", MMddyyyy);
    System.out.println(parse);

    // 5. 레거시 API 지원
    // GregorianCalendar와 Date 타입의 인스턴스를 Instant나 ZonedDateTime으로 변환 가능.
    // java.util.TimeZone에서 java.time.ZoneId로 상호 변환 가능.
    Date date = new Date();
    Instant instant2 = date.toInstant();
    Date nowDate = Date.from(instant2);

    GregorianCalendar gregorianCalendar = new GregorianCalendar();
    ZonedDateTime dateTime = gregorianCalendar.toInstant().atZone(ZoneId.systemDefault());
    GregorianCalendar from = GregorianCalendar.from(dateTime);

    ZoneId newZoneAPI = TimeZone.getTimeZone("PST").toZoneId();
    TimeZone legacyZoneAPI = TimeZone.getTimeZone(newZoneAPI);

    Instant newInstant = new Date().toInstant();
    Date legacyInstant = Date.from(newInstant);
  }

}

 

 

 

참고

 

 

 

'프로그래밍 > Java' 카테고리의 다른 글

CompletableFuture (2) - Excutors  (0) 2022.05.06
CompletableFuture (1) - 자바 Concurrent 프로그래밍 소개  (0) 2022.05.06
Optional  (0) 2022.05.05
Stream  (0) 2022.05.04
Lombok 동작원리  (0) 2022.05.03