Language/Java

[Java] Java에서 날짜, 시간(Date, Time) 다루기

별토끼. 2021. 7. 31. 23:13
반응형

일할 때 굉~장히 많이 사용하는 날짜와 시간. 책 언저리에서 보고 이렇게 쓰면 되겠지 하고 넘겼다가 한참을 삽질하여 포스팅까지 하게 되었다. 뭐든 대충하면 안된다. 정확히 알고 넘어가야지.

목표

  • 타임존과 국제 표준 이해
  • 날짜, 시간 API 종류 파악
  • 사용 방법
  • 유용한 메서드

타임존

타임존은 동일한 로컬 시간을 따르는 지역을 의미한다. 보통 국가별로 고유 타임존을 사용하며, 면적이 넓은 나라는 지역별로 다른 타임존을 사용한다.

시스템과 플랫폼 간의 의사소통을 하는 API의 대중화, 서비스 지역의 세계화로 인해 타임존 정보를 적절하게 가공하는 것이 중요해졌다.

타임존의 종류

브라우저에 따라 기본 설정이 다를 수 있다. 차이는 1초 미만이라 신경쓰지 않아도 된다.

GMT(GreenWich Mean Time)

한국의 타임존은 보통 GMT +09:00으로 표현된다. 영국 그리니치 천문대 기준으로 하는 태양 시간.

UTC

지구 자전 주기의 흐름이 늦어지고 있는 문제를 해결한 시간. GMT를 대체하기 위한 새로운 표준. GMT와 아주 미세한 차이인데, 소프트웨어에서 사용할 때는 UTC가 더 정확한 표현이다.

Offset

UTC+09:00에서 +09:00의 의미는 UTC 기준 시간보다 9시간 빠르다는 의미이다. 즉, UTC 12시이면, 한국시간으로 9시라는 것이다. 이처럼, UTC와의 차이를 나타낸 것을 Offset이라고 한다.

보통 국가나 지역마다 자신이 사용하는 타임존에 대해 고유 이름을 부여한다. 대한민국의 타임존은 KST(Korea Standard Time)이라고 부른다. KST = UTC+09:00 이라고 이해하면 쉽다.

한 지역의 타임존은 하나 이상의 오프셋을 갖는다. 해당 지역의 정치/경제적 상황에 따라 계속해서 달라질 수 있다.

ISO 8610

날짜와 시간 관련된 데이터 교환을 다루는 국제 표준. 국제 표준화 기구(ISO)에 의해 공포되었고, 1988에 처음으로 공개되었다.

형식

2021-07-19T17:40:00+09:00
  • 날짜 : 년-월-일의 형태로 나와있다.
  • T : 날짜 뒤에 시간이 오는 것을 표시해주는 문자
  • 시간 : 시:분:초 형태. 언어에 따라 초 뒤에 소수점 형태로 milliseconds가 표시되기도 한다.
  • Timezone Offset : 시간 뒤에 +/-시간:분 형태 나타냄
  • Z or +00:00 : UTC 기준시를 나태내는 표시
// 로컬 시간
2021-07-19T17:40:00.000

//UTC(GMT)
2021-07-19T17:40:00.000Z

//로컬 시간을 의미하면서 UTC(GMT) 대비 +09:00 임을 의미
2021-07-19T17:40:00.000+09:00

JDK1.8 이전

java.util패키지에 Date 클래스가 존재한다. JDK1.0부터 제공되어온 클래스이다. JDK1.1에서는 Calendar 클래스도 나왔다. Calendar 추가 후 Date의 대부분이 deprecated 됐다.

형식화 클래스

java.text 패키지에 포함되어 있으며, 숫자, 날짜, 텍스트 데이터를 일정한 형식에 맞게 표현할 수 있다. 객체지향적 설계하여 표준화했다.

SimpleDateFormat

Date와 Calendar만으로 형태 출력이 불편할 때, 요것을 많이 썼다.

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

Java.time 패키지

기존 java에 있던 Date, Calendar 클래스의 단점을 해소하기 위해 JDK1.8부터 java.time 패키지가 추가되었다.

java.time : 날짜와 시간을 다루는데 필요한 핵심 클래스들을 제공
java.time.chrono : 표준(ISO)이 아닌 달력 시스템을 위한 클래스들을 제공
java.time.format : 날짜와 시간을 파싱하고, 형식화하기 위한 클래스들을 제공
java.time.temporal : 날짜와 시간의 필드(field)와 단위(unit)를 위한 클래스들을 제공
java.time.zone : 시간대(time-zone)와 관련된 클래스들을 제공

가장 큰 특징은 String 클래스처럼 불변(Immutable) 하다는 것. 그래서 항상 새로운 객체를 반환한다.

핵심 클래스

LocalDateTime

Zone 구분이 없이 Local 시간을 나타낸다.
시간 표현 : LocalTime 클래스
날짜 표현 : LocalDate 클래스
둘 다 표현 시, LocalDateTime를 사용한다.

ZonedDateTime

Zone을 구분하는 시간을 나타낸다. 2021-07-19T17:40:00.000++09:00[Asia/Seoul]
LocalDateTime + 시간대 : ZonedDateTime 클래스

ZoneId zoneId = ZoneId.of("Asia/Seoul");
//ZoneId zoneId = ZoneId.of("America/New_York");
ZonedDateTime zoneDateTime = dateTime.atZone(zoneId);
System.out.println(zoneDateTime); // 2021-07-19T17:40:00.000+09:00[Asia/Seoul]

ZoneOffset

UTC로부터 얼만큼 떨어져있는지 ZoneOffset으로 표현한다. 서울은 +9, 미국 뉴욕은 -4이다.

ZoneOffset krOffset = ZonedDateTime.now().getOffset();
int krOffsetInSec = KrOffset.get(ChronoField.OFFSET_SECONDS); // 32400초

OffsetDateTime

ZonedDateTime은 ZoneId로 구역을 표현하지만, ZoneOffset을 사용하는 것은 OffsetDateTime이다. ZoneId는 일광절약시간 같은 시간대 관련 규칙을 포함하지만 ZoneOffset은 시간의 차이로만 구분한다. 그래서 컴퓨터 통신 간에는 계절별로 시간을 뺏다 더했다 하는 것 보다 안전한 OffsetDateTime을 이용한다.

Parsing & Format

java.time.format 패키지에 들어있는 DateTimeFormatter와 parse 메서드를 사용한다.

Date To String

LocalDate localDate = LocalDate.of(2021, 7, 19);
String localDateString = DateTimeFormatter.ISO_LOCAL_DATE.format(localDate); // "2021-07-19"
String localDateString = localDate.format(DateTimeFormatter.ISO_LOCAL_DATE); // "2021-07-19"

String to Date

LocalDateTime localDateTime = LocalDateTime.parse("2021-07-19T00:00:00");

차이 계산

항상 헷갈리는 날짜 계산. 이번에 확실히 기억해두자.
date1 : 5/22
date2 : 7/19
경우, date1 - date2 는 양수로 표현된다.

//날짜 간 계산은 between 메서드를 사용한다.
LocalDate date1 = LocalDate.of(2021,5,22);
LocalDate date2 = LocalDate.of(2021,7,19);
Period period = Period.between(date1, date2);

참고
https://meetup.toast.com/posts/125
https://jongmin92.github.io/2018/06/06/Java/java-date-time/
https://perfectacle.github.io/2018/09/26/java8-date-time/

반응형