Java 프로젝트에서 Default Time Zone은 어떻게 설정되는가?

ASHAPPYASIKNOW·2022년 7월 3일
2

JAVA

목록 보기
1/1
post-thumbnail

1. Default Time Zone 설정 방식

우선순위에 따라서 1 -> 2 -> 3번 순으로 진행 됨

  1. Java 프로그램 실행 시 설정한 "user.timezone"
  2. 운영체제(Linux, Windows ...)에 설정된 Time Zone의 값
  3. GMT를 기본값으로 설정

프로젝트에서 값 확인하기

I. IntelliJ 예제 Project 생성

IntelliJ 예제 Project 생성

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>me.kevin</groupId>
    <artifactId>zoned-date-time-example</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

</project>

II. 기본 Main class 생성

  1. me.kevin pacakge 생성
  2. Main class 생성
package me.kevin;

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}

실행하면 "Hello World" 출력 환인 가능
Hello World

2. DefaultTimeZone 확인

I. 소스코드 작성

package me.kevin;

import java.util.TimeZone;

public class Main {
    public static void main(String[] args) {
        System.out.println("------------------------------------------------------------------------------------------");
        System.out.printf("DisplayName: %s, ID: %s, Offset: %s%n",
                TimeZone.getDefault().getDisplayName(),
                TimeZone.getDefault().getID(),
                TimeZone.getDefault().getRawOffset());
        System.out.println("------------------------------------------------------------------------------------------");
    }
}

결과 확인

------------------------------------------------------------------------------------------
DisplayName: Korean Standard Time, ID: Asia/Seoul, Offset: 32400000
------------------------------------------------------------------------------------------

II. VMOption 적용 및 확인

-Duser.timezone=Asia/Bangkok

VMOption 적용

결과 확인

------------------------------------------------------------------------------------------
DisplayName: Indochina Time, ID: Asia/Bangkok, Offset: 25200000
------------------------------------------------------------------------------------------

III. OS 시간 변경 및 확인

OS 시간 변경 및 확인

결과 확인

------------------------------------------------------------------------------------------
DisplayName: Fiji Standard Time, ID: Pacific/Fiji, Offset: 43200000
------------------------------------------------------------------------------------------

3. Timezone Default 설정 정책 분석

I. Default Time을 얻어오는 과정 확인

package java.util.Timezone 확인

...
    public static TimeZone getDefault() {
        return (TimeZone) getDefaultRef().clone();
    }
    
    static TimeZone getDefaultRef() {
        TimeZone defaultZone = defaultTimeZone;
        if (defaultZone == null) {
            // Need to initialize the default time zone.
            defaultZone = setDefaultZone();
            assert defaultZone != null;
        }
        // Don't clone here.
        return defaultZone;
    }
...

getDefault() --> getDefaultRef() --> setDefaultZone()

설정된 defaultZone 이 없는 경우 setDefaultZone() 함수를 이용해서 만들어 낸다.

 private static synchronized TimeZone setDefaultZone() {
        TimeZone tz;
        // get the time zone ID from the system properties
        Properties props = GetPropertyAction.privilegedGetProperties();
        String zoneID = props.getProperty("user.timezone");

        // if the time zone ID is not set (yet), perform the
        // platform to Java time zone ID mapping.
        if (zoneID == null || zoneID.isEmpty()) {
            String javaHome = StaticProperty.javaHome();
            try {
                zoneID = getSystemTimeZoneID(javaHome);
                if (zoneID == null) {
                    zoneID = GMT_ID;
                }
            } catch (NullPointerException e) {
                zoneID = GMT_ID;
            }
        }

        // Get the time zone for zoneID. But not fall back to
        // "GMT" here.
        tz = getTimeZone(zoneID, false);

        if (tz == null) {
            // If the given zone ID is unknown in Java, try to
            // get the GMT-offset-based time zone ID,
            // a.k.a. custom time zone ID (e.g., "GMT-08:00").
            String gmtOffsetID = getSystemGMTOffsetID();
            if (gmtOffsetID != null) {
                zoneID = gmtOffsetID;
            }
            tz = getTimeZone(zoneID, true);
        }
        assert tz != null;

        final String id = zoneID;
        props.setProperty("user.timezone", id);

        defaultTimeZone = tz;
        return tz;
    }

a. user.timzone 확인

java -Duser.timezone=Asia/Seoul me.kevin.Main

-Duser.timezone option으로 실행한 경우 "user.timezone" 으로 값을 읽을 수 있다.

b. getSystemTimeZoneID(javaHome)

OS에서 기본으로 설정된 timeZone 값을 읽어 올 수 있다.

Linux Time Zone 확인

ls -l /etc/localtime
lrwxrwxrwx 1 root root 30 Jul 4 07:10 /etc/localtime -> /usr/share/zoneinfo/Asia/Seoul

Windows 11 Time Zone 확인

Control Panel -> Date and Time -> Cahnge time zone... -> Time zone

Windows 11 time zone 설정

c. GMT 로 설정

위의 과정에서 모두 실패하였다면 기본정책으로 GMT가 선택되는 것을 확인할 수 있다.

References

How to Set the JVM Timezone

profile
36.9 It's good time to start something new

1개의 댓글

comment-user-thumbnail
2022년 10월 21일

좋은글 감사합니다!

답글 달기