LocalDateTime
은 TZ(TimeZone)를 포함하지않습니다. 하지만, TZ로 인해서 문제가 생길 수도 있습니다.
서버 환경 내에서의 TZ
가 내가 예상한 TZ 가 아닐 경우, 우리는 타임머신을 탄 경험을 하게 됩니다.. 쉽게 말하면, 완전 일자가 달라진다는 얘기입니다.
내가 원하던 LocalDateTime
의 정보가 2022-05-16T18:36:25.400357 라고 가정한다면, 서버 환경 내의 TZ로 인해서 1980-05-16T18:36:25.400357 이라는 아예 다른 시간 데이터가 도출될 수도 있다는 것입니다.
이를 막기 위해서는 시스템 내에서 TZ 를 적용할 수도 있지만, 그렇게 된다면 서버가 변경될 때마다 TZ 를 재적용해야하는 번거로움이 존재하게 됩니다.
그렇기 때문에 Application-Level 에서 이를 설정할 수 있습니다.
Application 레벨에서의 설정을 설명하기 이전에 해당 절차가 얼마나 번거로운지를 보여주기 위해서 적용하는 방법에 대해서 소개하겠습니다.
번거롭지않다면, 해당 방법을 사용해도 괜찮습니다. 이는 개발자에 대한 개인 선호도에 따라서 어떤 방식으로 TZ를 설정하는지에는 차이가 있습니다.
$ timedatectl
Local time: Fri 2023-03-24 07:28:18 UTC
Universal time: Fri 2023-03-24 07:28:18 UTC
RTC time: Fri 2023-03-24 07:28:18
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
$
$ sudo timedatectl set-timezone Asia/Seoul
명령어 자체는 아주 심플하고 간단해보입니다. 하지만, 다른 서버에서 해당 환경을 적용하려고하면 다시 해당 명령을 작성해야합니다.
사람에 따라서 해당 동작이 굉장히 귀찮을 수도, 또는 굉장히 편할 수도 있습니다. 만약 이러한 동작을 Application 레벨에서 제어하고 이를 통해서 해당 Application 에 별도의 TZ 가 설정될 수 있다면 해당 작업을 반복할 필요가 없어집니다.
import java.time.Clock;
import java.time.ZoneId;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ClockConfig {
@Bean
public Clock clock() {
return Clock.system(ZoneId.of("Asia/Seoul"));
}
}
해당 코드를 통해서 Spring Application 내에서 Clock 에 대한 TZ 를 명시적으로 선언해줄 수 있습니다. 이렇게 되면, Application 자체에서 해당 TZ를 가지게 되어 별도의 시스템에서의 설정은 필요하지 않게 됩니다.
Clock
클래스는 Java 8부터 도입된java.time
패키지의 일부로, 시간과 날짜를 측정하는 데 사용되는 추상 클래스입니다.
Clock
은 시스템 시계(System Clock), 고정 시계(Fixed Clock), 또는 오프셋 시계(Offset Clock)와 같은 다양한 구현을 제공하며, 시간과 날짜 관련 작업을 보다 유연하고 명확하게 할 수 있도록 설계되었습니다.
TZ에 대한 문제는 생각보다 민감한 문제입니다. 테스트에 대한 오류를 유발하거나, 데이터의 무결성을 잃게 되는 원인으로써 작용하기도 합니다.
이를 막기 위해서 앞서 소개한 2가지의 방법에 대해서 잘 선택하여 사용하면 보다 무결성이 잘 보장된 어플리케이션을 구축할 수 있을 것 입니다.