Cara mengatur JVM TimeZone dengan Benar

141

Saya mencoba menjalankan program Java, tetapi mengambil zona waktu GMT default, bukan zona waktu yang ditentukan OS. Versi JDK saya adalah 1.5 dan OSnya adalah Windows Server Enterprise (2007)

Windows memiliki zona waktu Central yang ditentukan, tetapi ketika saya menjalankan program berikut, itu memberi saya waktu GMT.

import java.util.Calendar;

public class DateTest
{
    public static void main(String[] args)
    {
        Calendar now = Calendar.getInstance();
        System.out.println(now.getTimeZone());
        System.out.println(now.getTime());
    }
}

Ini outputnya

sun.util.calendar.ZoneInfo[id="GMT",
offset=0,
dstSavings=0,
useDaylight=false,
transitions=0,
lastRule=null]
Mon Mar 22 13:46:45 GMT 2010

Harap dicatat bahwa saya tidak ingin mengatur zona waktu dari aplikasi. Saya ingin zona waktu yang digunakan oleh JVM harus menjadi yang ditentukan dalam OS. (Saya tidak menemukan masalah ini dengan server lain yang memiliki versi 1.4 dari JDK dan Microsoft Server 2003).

Pikiran apa pun akan sangat dihargai.

Kushal Paudyal
sumber
1
Hm, itu aneh. Sepertinya bug JVM / OS atau kesalahan konfigurasi yang aneh.
Michael Borgwardt
bagaimana Anda memohon DateTestkelas?
matt b
@ Matt b: Saya mengkompilasi dan memanggil DateTest dari command prompt windows. Tapi ini hanya kelas Tes. Masalah aslinya adalah dengan beberapa proses ETL untuk server cognos IBM.
Kushal Paudyal
1
hanya ingin mengesampingkan peluncurannya melalui skrip shell / batch yang mungkin meneruskan -Duser.timezonenilai
matt b

Jawaban:

220

Anda dapat melewati JVM param ini

-Duser.timezone

Sebagai contoh

-Duser.timezone=Europe/Sofia

dan ini harus melakukan trik. Pengaturan variabel lingkungan TZ juga melakukan trik di Linux.

Bozhidar Batsov
sumber
Kami harus menggunakan JDK DST Timezone Update Tool - 1.3.25 (tzupdater) dan kemudian mengubah parameter JVM seperti yang Anda sarankan dan akhirnya kami menyingkirkan masalah tersebut. By the way, informasi zona waktu disimpan oleh Windows di beberapa registri. Pemutakhiran yang saya gunakan juga memperbarui nilai registri.
Kushal Paudyal
1
Saya mencoba memulai JVM saya menggunakan parameter ini, tetapi sepertinya tidak ada perubahan ... Jika saya ingin memulai di UTC apa yang harus saya gunakan sebagai parameter !?
rafa.ferreira
Dalam aplikasi saya, saya mengubah beberapa lokasi dan mendapatkan zona waktu dari lokasi itu. Menggunakan zona waktu saya memproses lebih lanjut. Tetapi ketika aplikasi dimulai untuk pertama kalinya, saya mendapatkan nilai yang benar. Ketika saya mengubah TimeZone dan mengatur zona waktu baru sebagai zona waktu default, saya tidak mendapatkan nilai yang benar. Apa masalahnya? Bagaimana cara mengubah zona waktu secara tepat. Saya mengubah zona waktu menggunakan TimeZone.setDefault (TimeZone.getTimeZone ("my_time_zone"));
Dray
2
Daftar zona waktu untuk TZ ada di sini: en.wikipedia.org/wiki/List_of_tz_database_time_zones . Menggunakan nama zona waktu lebih baik daripada offset karena akan menangani penghematan siang hari.
Brian
65

Anda juga dapat mengatur zona waktu default dalam kode Anda dengan menggunakan kode berikut.

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

Untuk Anda

 TimeZone.setDefault(TimeZone.getTimeZone("Europe/Sofia"));
Ali786
sumber
1
"Harap dicatat bahwa saya tidak ingin mengatur zona waktu dari aplikasi."
AbVog
22

Jawaban yang diterima di atas:

-Duser.timezone="Europe/Sofia" 

Sebenarnya tidak bekerja untuk saya. Saya hanya berhasil mengubah zona waktu ketika saya tidak memiliki tanda kutip di parameter:

-Duser.timezone=Europe/Sofia
WN4yhihiY
sumber
2
Saya setuju. Saya telah mengedit jawaban asli untuk menghapus tanda kutip.
GaZ
1
Ini tergantung pada shell yang digunakan.
vadipp
10

Pada windows 7 dan untuk JDK6, saya harus menambahkan -Duser.timezone="Europe/Sofia"ke JAVA_TOOL_OPTIONS variabel sistem yang terletak di bawah "Komputer saya => Properties => Advanced System Settings => Variabel Lingkungan".

Jika Anda sudah memiliki properti lain yang disetel untuk JAVA_TOOL_OPTIONShanya menambahkan spasi dan kemudian masukkan string properti Anda.

VolkanT
sumber
5

Dua opsi yang menurut saya tidak tercakup dalam jawaban lain:

Hindari kebutuhan

Apa pun yang Anda lakukan untuk mengatur zona waktu default JVM, sangat sulit untuk memastikan bahwa tidak ada orang lain yang menetapkannya secara berbeda. Itu dapat diatur kapan saja tanpa pemberitahuan dari bagian lain dari program Anda atau dari program lain yang berjalan di JVM yang sama. Jadi dalam operasi waktu Anda secara eksplisit tentang zona waktu yang Anda inginkan, dan Anda akan selalu tahu apa yang Anda dapatkan secara independen dari pengaturan JVM. Contoh:

    System.out.println(ZonedDateTime.now(ZoneId.of("Asia/Dushanbe")));

Contoh output:

2018-10-11T14: 59: 16.742020 + 05:00 [Asia / Dushanbe]

System.setProperty

Untuk banyak tujuan berikut ini tidak akan menjadi cara yang disukai, dan tentu saja dapat disalahgunakan. Untuk program “buang” saya terkadang merasa praktis. Anda juga dapat mengatur properti sistem dari dalam Java:

    System.setProperty("user.timezone", "Australia/Tasmania");
    System.out.println(ZonedDateTime.now());

Ini baru saja dicetak:

2018-10-11T21: 03: 12.218959 + 11:00 [Australia / Tasmania]

Jika Anda ingin validasi string yang Anda berikan, gunakan:

        System.setProperty("user.timezone", ZoneId.of("Australia/Tasmania").getId());
Ole VV
sumber
4

Jika Anda menggunakan Maven :

mvn -Dexec.args="-Duser.timezone=Europe/Sofia ....."
MichalSv
sumber
mvn spring-boot:run -Drun.jvmArguments="-Duser.timezone=UTC"untuk Spring Boot v1.
Chloe
0

Di win7, jika Anda ingin mengatur zona waktu yang benar sebagai parameter di JRE, Anda harus mengedit file yang deployment.propertiesdisimpan di jalur c:\users\%username%\appdata\locallow\sun\java\deploymentmenambahkan string deployment.javaws.jre.1.args=-Duser.timezone\=my_time_zone

Dave
sumber
Saya mencobanya dan tidak berhasil (jvm dijalankan dari dalam intellij)
kumetix