Date와 Time 소개

Java 8에서 새로운 날짜와 시간 API가 만들어진 이유

  • 이전에 사용하던 java.util.Date 클래스는 mutable하기 때문에 thread safe 하지 않다. (Set이 가능하다.)
    • 새로 나온 LocalDate는 immutable하다! (java.time.*에 있음)
  • 클래스 이름이 명확하지 않다. Date지만 시간을 다룬다.
  • 버그가 발생할 여지가 많다. (타입 안정성이 없고, 월이 0부터 시작한다... 등등)
  • 날짜 시간 처리가 복잡한 애플리케이션에는 보통 Joda Time을 쓰곤 했다. 

Month의 경우 MagicConstant로 매직넘버도 가능하고, 기존 달인 1~12가아닌 0~11로 주의해서 사용해야 한다.

 

Java 8에서 제공하는 Date-Time API

  • JSR-310 스펙의 구현체를 제공한다.
  • 디자인 철학
    • Clear
    • Fluent
    • Immutable
    • Extensible

 

주요 API

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

 

Date와 Time API
지금 시간을 기계 시간으로 표현하는 방법

  • Instant.now()
    • 현재 UTC (GMT)를 리턴
  • Universal Time Coordinated == Gereenwich Mean Time
Instant now = Instant.now();
System.out.println(now);        // 기준 UTC
System.out.println(now.atZone(ZoneId.of("UTC")));   // 위와 같음

System.out.println(ZoneId.systemDefault());     // 시스템 기준 시점
ZonedDateTime zonedDateTime = now.atZone(ZoneId.systemDefault()); // 시스템 기준 시점 시간
System.out.println(zonedDateTime);

 

인류용 일시를 표현하는 방법

  • LocalDateTime.now()
    • 현재 시스템 Zone에 해당하는 일시를 리턴 (로컬 시간)
  • LocalDateTime.of(int, Month, int, int, int, int)
    • 로컬의 특정 일시를 리턴
  • LocalDateTime.of(int, Month, int, int, int, int, ZoneId)
    • 특정 Zone의 특정 일시를 리턴
LocalDateTime now = LocalDateTime.now();    // Local은 시스템 정보 확인해서 시간을 가져옴
System.out.println(now);

LocalDateTime birthDay = LocalDateTime.of(1995, Month.MARCH, 10, 0, 0, 0);
ZonedDateTime nowInKorea = ZonedDateTime.now(ZoneId.of("Asia/Seoul"));
System.out.println("birthDay : " + birthDay);
System.out.println("korea : " + nowInKorea);

 

기간을 표현하는 방법

  • Period / Duration .between()

 

 

파싱 또는 포매팅

// 포맷
LocalDateTime now = LocalDateTime.now();
System.out.println(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
DateTimeFormatter MMddyyyy = DateTimeFormatter.ofPattern("MM/dd/yyyy");
System.out.println(now.format(MMddyyyy));       // 10/13/2022

// 파싱
DateTimeFormatter MMddyyyy = DateTimeFormatter.ofPattern("MM/dd/yyyy");
LocalDate birthDay = LocalDate.parse("03/10/1995", MMddyyyy);
System.out.println(birthDay);       // 1995-03-10

 

레거시 API 지원

  • GregorianCalendar와 Date 타입의 인스턴스를 Instant나 ZonedDateTime으로 변환 가능
  • java.util.TimeZone 에서 java.time.ZoneId로 상호 변환 가능
Date date = new Date();
Instant instant = date.toInstant();
Date newDate = Date.from(instant);

GregorianCalendar gregorianCalendar = new GregorianCalendar();
LocalDateTime now = gregorianCalendar.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();

 

 

 

 

 

 

'JAVA' 카테고리의 다른 글

[JAVA 8] ParallelSort  (0) 2022.10.15
[Java 8] CompletableFuture  (0) 2022.10.13
[Java 8] Optional  (0) 2022.10.07
[JAVA 8] Stream  (0) 2022.10.06
[JAVA 8] 인터페이스의 변화  (0) 2022.10.06

+ Recent posts