문제 상황
외부 API 호출 시에 응답값으로 시간을 UTC 기준 Timestamp 값으로 전달받게 됐다.
이것을 프론트에 현재 시간 KST 기준으로 표시를 해줘야 했는데 변환이 처음에 잘 되지 않아서 엄청 헤맸어서 기록해둔다.
해결 방안
- long 값을 Date 값으로 변환
long timestamp = 100000000L;
ZonedDateTime date = Instant.ofEpochMilli(timestamp).atZone(ZoneId.systemDefault());
- Instant.ofEpochMilli 를 통해 timestamp 값을 Instant 클래스로 변환하고, zone 을 알맞게 변경하기 위해 ZonedDateTime 클래스로 변환한다.
- 여기서 atZone(ZoneId.of("UTC")) 를 통해 바로 UTC 기준 값으로 변경해보려고 하였으나 받은 값을 시스템 기준 zone 에서 UTC로 바뀌어 9시간 정도 차이가 나는 값으로 반환됐다.
- 예를 들어, UTC 기준 2025-01-01 12:00:00 값이 표시가 되어야 하는데 KST 기준 2025-01-01 12:00:00 값이 되었다가 UTC 기준 2025-01-01 03:00:00 으로 표시되어 버리는 것이다.
- Date 값의 Zone 을 UTC 기준으로 설정
date.withZoneSameLocal(ZoneOffset.UTC)
- withZoneSameLocal : 동일한 로컬 날짜와 시간을 지정된 시간대의 ZonedDateTime 으로 변환하여 반환
- 위 설정을 통해서 변환된 Date 값을 그대로 UTC 로 변환해준다.
- 예를 들어, KST 2025-01-01 12:00:00 시간을 UTC 2025-01-01 12:00:00 시간으로 변경해주는 것이다.
- UTC 기준으로 설정된 값을 KST 기준으로 변경
date.withZoneSameInstant(ZoneId.systemDefault())
- withZoneSameInstant : 같은 순간의 시간을 다른 시간대로 변환하여 반환
- 위 설정을 통해서 UTC 기준 Date 값을 KST 기준으로 변환해준다.
- 예를 들어, UTC 2025-01-01 12:00:00 시간을 KST 기준으로 변경하여 KST 2025-01-01 21:00:00 으로 변경해주는 것이다.
- LocalDateTime 으로 변경 후 포맷팅
date.toLocalDateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
- String 값으로 표시해주기 위해서 LocalDateTime 변환 후 DateTimeFormatter를 활용해준다.