Java에서 LocalDateTime.now()
를 사용하면 로컬 서버에서는 로컬 시간에 맞춰 지금 시간을 구할 수 있다. (한국 시간 기준 UTC+9) 그런데 EC2에 배포한 서버에서 해당 코드가 UTC 기준으로 실행되어 로컬의 현재 시간과 맞지 않는 문제가 발생하였다.
구매 참여한 시간 : 6월 7일 오후 6시
실제로 참여된 시간 : 6월 7일 오전 9시
이 문제를 해결하기 위한 방법으로 몇 가지가 있다.
@SpringBootApplication
public class MyApplication {
@PostConstruct
void started() {
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul"));
}
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
첫 번째 방법은 Application에 @PostConstruct
애너테이션을 활용하여 타임존 설정을 추가해주는 것이다. @PostConstruct
는 Spring Bean이 초기화된 후에 실행되는 메서드를 의미하며 애플리케이션의 시작 지점에 started 메서드가 자동으로 호출된다. 해당 메서드의 타임존 설정을 통해 애플리케이션의 전체 시간대가 지정한 시간대로 설정된다.
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Asia/Seoul"));
두 번째 방법은 기존에 사용하던 LocalDateTime
대신 ZonedDateTime
을 사용하는 것이다. ZonedDateTime.now
로 현재 시각과 함께 시간대 정보를 포함할 수 있다.
그러나 이러한 설정 방법으로도 서버 시간이 변경되지 않았는데.... 우리는 도커 이미지로 배포를 하고 있었기 때문이었다. 즉 도커 컨테이너의 시간이 UTC로 되어 있는 것이므로 이를 변경해주어야 했다.
date 명령어를 실행하면 UTC로 설정되어 있는 것을 확인할 수 있다.
docker run -d -p 80:8080 -e TZ=Asia/Seoul {docker image}
docker run 명령 실행시 타임존 설정을 추가하여 실행할 수 있다.
# Java 실행 환경
FROM openjdk:17
# 타임존 설정
ENV TZ=Asia/Seoul
# 애플리케이션 파일 복사
COPY build/libs/cukz-0.0.1-SNAPSHOT-plain.jar app.jar
# 애플리케이션 실행
ENTRYPOINT ["java","-jar","/app.jar"]
도커 파일에 타임존을 설정하는 환경 변수를 추가한 뒤 해당 도커 파일을 사용하여 도커 이미지를 빌드하고 실행 할 수 있다.
이제 타임존 설정이 변경되어 잘 적용된 것을 볼 수 있다.