[Java 8] Date와 Time API

홍정완·2022년 6월 19일
0

Java

목록 보기
9/25
post-thumbnail

Date와 Time API 소개


자바 8에서 새로운 날짜와 시간 API가 생긴 이유


  • java.util.Date Class는 mutable(변하기 쉬운) 하기 때문에 쓰레드가 안전하지 않다.

  • Class 이름이 명확하지 않다. Date인데 시간까지 다룬다.

  • 버그 발생 여지가 많다

    • 타입 안정성이 없다
    • 월이 0부터 시작



public static void main(String[] args) throws InterruptedException {

        Date date = new Date();
        long time = date.getTime();

        System.out.println(date);
        System.out.println(time);

        Thread.sleep(1000 * 3);
        Date after3Seconds = new Date();

        System.out.println(after3Seconds);

        date.setTime(time); // mutable
        System.out.println(after3Seconds);

    }



주요 API


  • 기계용 시간 (machine time) & 인류용 시간(human time)으로 나눌 수 있다.

  • 기계용 시간은 EPOCK (1970년 1월 1일 0시 0분 0초)부터 현재까지의 타임스탬프를 표현

  • 인류용 시간은 우리가 흔히 사용하는 연, 월, 일, 시, 분, 초 등을 표현

  • 타임스탬프는 Instant를 사용

  • 특정 날짜(LocalDate), 시간(LocalTime), 일시(LocalDateTime)

  • 기간을 표현할 때 Duration (시간 기반), Period (날짜 기반)

  • DateTimeFormatter를 사용해서 일시를 특정한 문자열로 포매팅




Date와 Time API


현재를 기계용 시간으로 표현

  • Instant.now()

    • 현재 UTC (GMT)를 리턴

public static void main(String[] args) throws InterruptedException {

        Instant instant = Instant.now();
        System.out.println(instant); // 그린위치 기준시. 2022-06-19T02:39:42.211605900Z

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

        ZonedDateTime zonedDateTime = instant.atZone(zone);
        System.out.println(zonedDateTime); // 2022-06-19T11:39:42.211605900+09:00[Asia/Seoul]

    }



인류용 일시 표현

  • LocalDateTime.now()

    • 현재 시스템 Zone에 해당하는(로컬) 일시를 리턴

  • LocalDateTime.of(int, Month, int, int, int, int)

    • 로컬의 특정 일시를 리턴

  • ZonedDateTime.of(int, Month, int, int, int, int, ZoneId)

    • 특정 Zone의 특정 일시를 리턴

public static void main(String[] args) throws InterruptedException {

        LocalDateTime now = LocalDateTime.now();
        System.out.println(now); // 2022-06-19T11:51:21.152290700

        LocalDateTime birthday = LocalDateTime.of(1998, Month.APRIL, 3, 0, 0, 0);
        System.out.println(birthday); // 1998-04-03T00:00

        ZonedDateTime nowInKorea = ZonedDateTime.now(ZoneId.of("Asia/Seoul"));
        System.out.println(nowInKorea); // 2022-06-19T11:52:08.388910700+09:00[Asia/Seoul]

        Instant nowInstant = Instant.now();
        ZonedDateTime zonedDateTime = nowInstant.atZone(ZoneId.of("Asia/Seoul")); // Instant -> ZonedDateTime
        System.out.println(zonedDateTime); // 2022-06-19T11:52:08.388910700+09:00[Asia/Seoul]

        zonedDateTime.toInstant(); // Instant로 변환 가능

    }



기간을 표현하는 방법

  • Period (날짜 기반) / Duration (시간 기반)
    • .between()

Period between = Period.between(today, birthDay);
System.out.println(between.get(ChronoUnit.DAYS));



파싱 또는 포매팅

// 포매팅
public static void main(String[] args) throws InterruptedException {

        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter MMddyyyy = DateTimeFormatter.ofPattern("MM/dd/yyyy");
        System.out.println(now.format(MMddyyyy));

    }

// 파싱
public static void main(String[] args) throws InterruptedException {
        DateTimeFormatter MMddyyyy = DateTimeFormatter.ofPattern("MM/dd/yyyy");
        LocalDate parse = LocalDate.parse("04/03/1998", MMddyyyy);
        System.out.println(parse);

    }



레거시 API 지원

  • 예전 API와 호환 가능

    • 서로 변환 가능

public static void main(String[] args) throws InterruptedException {

        Date date = new Date();

        Instant instant = date.toInstant(); // Date -> Instant
        Date newDate = Date.from(instant);  // Instant -> Date

        GregorianCalendar gregorianCalendar = new GregorianCalendar();
        LocalDateTime dateTime = gregorianCalendar
                .toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        // GregorianCalendar -> LocalDateTime

        GregorianCalendar from = GregorianCalendar.from(ZonedDateTime.now());
        // ZonedDateTime -> GregorianCalendar
    }
profile
습관이 전부다.

0개의 댓글