[java] LocalDateTime, ZonedDateTime, OffsetDateTime
환경: java11
java8이후로 java.util.Date, Calendar가 deprecated되고 LocalDateTime, ZonedDateTime, OffsetDateTime이 등장하였다. 각각 어떤 것인지 살펴보자.
LocalDateTime
날짜와 시간에 대한 정보만 있지 zone이나 offset에 대한 정보는 없다. zone에 상관없이 그냥 시간 그 자체를 담는 용도이다.
따라서 LocalDateTime을 아래처럼 포매팅하면 에러가 난다.
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX")
private LocalDateTime endRegDate;
Unsupported field: OffsetSeconds
지금 시간 가져오기
LocalDateTime now = LocalDateTime.now();
서울에서, 현재 시각이 2024-02-14 11:00:00 이면 위 결과값도 동일하게 11시이다.
특정 시간 가져오기
LocalDateTime now = LocalDateTime.of(2024, 1, 1, 0, 0, 0);
ZonedDateTime
LocalDateTime에 zone이 들어간 형태(UTC/Greenwich)
서머타임(Daylight Saving Time): 시간대 변환 시 서머타임을 고려해야!! ZonedDateTime은 서머타임을 자동으로 처리함
지금 시간 가져오기
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX")
ZonedDateTime now = ZonedDateTime.now();
//"2024-02-14T11:57:23.797+09"
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX")
ZonedDateTime.now(ZoneId.of("UTC"));
//"2024-02-14T02:57:23.797Z"
그냥 now는 서버 시스템 존(Asia/Seoul)을 기반으로 가져오고, zone id를 주면 변환된다.
포매팅할 때 X를 추가하면(Z아님..) 끝에 존 정보 +09 혹은 UTC면 Z가 들어간다.
특정 시간 가져오기
ZonedDateTime zonedDateTime = ZonedDateTime.of(2023, 12, 25, 10, 30, 0, 0, ZoneId.of("America/New_York"));
zone 정보를 줘야 한다.
참고: https://www.baeldung.com/java-format-zoned-datetime-string
OffsetDateTime
ZonedDateTime 처럼 zone을 기반으로 움직이는 데이터이지만 zoneId가 아닌 offset("+02:00", "-08:00")을 기반으로 한다.
특정 zone id를 모를 때 사용하기 좋음
현재 시간 가져오기
OffsetDateTime.now();
//"2024-02-14T12:10:05.884+09"
OffsetDateTime.now(ZoneId.of("UTC"));
//"2024-02-14T03:10:05.884Z"
사용법은 ZonedDateTime과 동일하다. 심지어 zone id로도 세팅 가능.
특정 시간 가져오기
OffsetDateTime offsetDateTime = OffsetDateTime.of(2023, 12, 25, 10, 30, 0, 0, ZoneOffset.ofHours(-5));
zone offset으로 시간을 줘야 한다.
Instant:
- Instant는 시간대와 상관없이 UTC 시간을 기준으로 시간을 관리할 때 유용
- 타임존 정보를 포함하지 않는 가장 기본적인 시간 표현 방식
- 즉, 1970-01-01T00:00:00Z(Epoch Time) 이후의 시간을 초 또는 나노초 단위로 계산한 시간
- 타임존과 무관하게 시간의 순간을 표현할 때 사용
- 네트워크 요청, 로그 등 글로벌 시스템에서 시간대를 고려하지 않고 순수 시간을 기록할 때 사용
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class TimeZoneConversionExample {
public static void main(String[] args) {
// 서버에서 UTC 시간으로 받은 Instant
Instant serverTime = Instant.now();
System.out.println("Server Time (UTC): " + serverTime);
// 사용자 시간대 (예: 아시아/서울 시간대)
ZonedDateTime userTime = serverTime.atZone(ZoneId.of("Asia/Seoul"));
System.out.println("User Time (Asia/Seoul): " + userTime);
}
}