[Java] timedatectl and Java TimeZone

1 minute read

Posted by Cho Hisabi. I was so surprised that I got sick.

Discovered while working on migrating a system built with Java from Amazon Linux to Amazon Linux 2.

In Amazon Linux 2, execute the following command to set the system time zone.

# timedatectl set-timezone "Asia/Tokyo"

Normally, this should be all OK, and even if you search the net, articles such as Amazon Linux 2 and CentOS 7 only mention Cocode.

However, TimeZone cannot be acquired correctly in the Java program, and it becomes UTC.

sample:

TimeZoneInfo.java


import java.util.Calendar;
class TimeZoneInfo {
  public static void main(String[] args) {
    Calendar cal = Calendar.getInstance();
    System.out.println(cal.getTimeZone());
    System.out.println(System.getProperty("user.timezone"));
  }
}

Execution result:

sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
UTC

There are several ways to handle this. (It took a long time to find)

  1. Set environment variable TZ=Asia/Tokyo
  2. Add -Duser.timezone=Asia/Tokyo to java command line
  3. Implement /etc/sysconfig/clock, which was the standard setting method for amazon linux

etc. I think there are some problems.

  • timedatectl rewrites /etc/localtime but not ```/etc/sysconfig/clock

    . (In the first place, it seems that there is no file on CentOS 7...)

    ```

  • Java doesn’t look at ```/etc/localtime

    . It depends on the version. It may be a change in the behavior of glibc, but the detailed cause is unknown.

    ```

  • Since it is systemd, /etc/sysconfig is not referenced much, but the legacy of the past remains, so please consider compatibility a little more. .. .. ..
  • Old system runs on Java 1.6, new system runs on Java 7. I don’t know what’s going on with Java 8 or newer.

I wonder which is the most correct (and should be done) response method. .. .. .. Or rather standardize about TimeZone settings.

Tags:

Updated: