반응형
문제
토스페이먼츠 API를 이용하던 중, 응답으로 주던 날짜 형식 "2024-10-02T21:16:13+09:00" 이 LocalDateTime으로 파싱이 되지 않았다.
해결
OffsetDateTime을 이용해서 파싱 할 수 있었다.
1. LocalDateTime 파싱 에러 발생
@Test
@DisplayName("LocalDateTime 파싱 - 에러남")
public void testLocalDateTimeParseException() {
// given
String rawTime = "2024-10-02T21:16:13+09:00";
// when & then
assertThatThrownBy(() -> LocalDateTime.parse(rawTime))
.isInstanceOf(java.time.format.DateTimeParseException.class);
}
LocalDateTime으로 파싱 시, DateTimeParseException이 발생한다.
2. OffsetDateTime 파싱
@Test
@DisplayName("OffsetDateTime 파싱")
public void testOffsetDateTimeParsing() {
// given
String rawTime = "2024-10-02T21:16:13+09:00";
// when
OffsetDateTime offsetDateTime = OffsetDateTime.parse(rawTime);
// then
assertThat(offsetDateTime.getOffset()).isEqualTo(ZoneOffset.of("+09:00"));
}
@Test
@DisplayName("OffsetDateTime 파싱 후 LocalDateTime 변환")
public void testOffsetDateTimeToLocalDateTime() {
// given
String rawTime = "2024-10-02T21:16:13+09:00";
OffsetDateTime offsetDateTime = OffsetDateTime.parse(rawTime);
// when
LocalDateTime localDateTime = offsetDateTime.toLocalDateTime();
// then
assertThat(localDateTime.getHour()).isEqualTo(21);
}
OffsetDateTime으로 변환하면 예외가 발생하지 않는다.
그리고 Offset을 가져오면 "+09:00"가 된다.
이를 "Asia/Seoul"로 변환하고 싶었는데, 아쉽게도 +9 시간대를 쓰는 시간대가 여러 개가 있을 수 있어서 변환이 되지 않았다.
3. offset 조정
@Test
@DisplayName("OffsetDateTime 조정 - 2시간 차이의 시간대로 변경")
public void testOffsetDateTimeAdjustment() {
// given
String rawTime = "2024-10-02T21:16:13+09:00";
// when
OffsetDateTime offsetDateTime = OffsetDateTime.parse(rawTime);
OffsetDateTime adjusted = offsetDateTime.withOffsetSameInstant(ZoneOffset.of("+07:00"));
// then
assertThat(adjusted.getHour()).isEqualTo(19);
}
Offset을 +7로 조정이 잘 되는지 테스트해보았다.
원래라면 21시였던 것이, 19시로 변경이 잘 된 것을 확인할 수 있다.
전체 테스트 코드
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
public class ZonedDateTimeTest {
@Test
@DisplayName("LocalDateTime 파싱 - 에러남")
public void testLocalDateTimeParseException() {
// given
String rawTime = "2024-10-02T21:16:13+09:00";
// when & then
assertThatThrownBy(() -> LocalDateTime.parse(rawTime))
.isInstanceOf(java.time.format.DateTimeParseException.class);
}
@Test
@DisplayName("OffsetDateTime 파싱")
public void testOffsetDateTimeParsing() {
// given
String rawTime = "2024-10-02T21:16:13+09:00";
// when
OffsetDateTime offsetDateTime = OffsetDateTime.parse(rawTime);
// then
assertThat(offsetDateTime.getOffset()).isEqualTo(ZoneOffset.of("+09:00"));
}
@Test
@DisplayName("OffsetDateTime 파싱 후 LocalDateTime 변환")
public void testOffsetDateTimeToLocalDateTime() {
// given
String rawTime = "2024-10-02T21:16:13+09:00";
OffsetDateTime offsetDateTime = OffsetDateTime.parse(rawTime);
// when
LocalDateTime localDateTime = offsetDateTime.toLocalDateTime();
// then
assertThat(localDateTime.getHour()).isEqualTo(21);
}
@Test
@DisplayName("OffsetDateTime 조정 - 2시간 차이의 시간대로 변경")
public void testOffsetDateTimeAdjustment() {
// given
String rawTime = "2024-10-02T21:16:13+09:00";
// when
OffsetDateTime offsetDateTime = OffsetDateTime.parse(rawTime);
OffsetDateTime adjusted = offsetDateTime.withOffsetSameInstant(ZoneOffset.of("+07:00"));
// then
assertThat(adjusted.getHour()).isEqualTo(19);
}
}
반응형
'TIL ✍️' 카테고리의 다른 글
TIL #117 : 인텔리제이 프로젝트 구조의 하위 디렉토리 전부 펼치기 단축키 (0) | 2024.11.13 |
---|---|
TIL #116 : 스프링/도커컴포즈에 Graceful shutdown 적용하기 (1) | 2024.11.13 |
TIL #114 : Spring Security 없이 PasswordEncoder 이용하기 (0) | 2024.11.13 |
TIL #113 : Assertj로 LocalDateTime.now() 단위 테스트 코드 작성하기 (0) | 2024.11.13 |
TIL #112 : 자바 애플리케이션을 도커 이미지로 만들 때 용량 줄이기 (6) | 2024.11.13 |