Come impostare correttamente un fuso orario JVM


141

Sto cercando di eseguire un programma Java, ma sta prendendo un fuso orario GMT predefinito invece di un fuso orario definito dal sistema operativo. La mia versione di JDK è 1.5 e il sistema operativo è Windows Server Enterprise (2007)

Windows ha un fuso orario centrale specificato, ma quando eseguo il seguente programma, mi dà un orario 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());
    }
}

Ecco l'output

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

Si noti che non desidero impostare il fuso orario dall'applicazione. Voglio che il fuso orario utilizzato da JVM sia quello specificato nel sistema operativo. (Non trovo questo problema con altri server con versione 1.4 di JDK e Microsoft Server 2003).

Ogni pensiero sarebbe molto apprezzato.


1
Hm, è strano. Sembra un bug JVM / OS o qualche strana configurazione errata.
Michael Borgwardt,

come stai invocando la DateTestclasse?
matt b

@matt b: sto compilando e chiamando DateTest dal prompt dei comandi di Windows. Ma questa è solo una lezione di prova. Il problema originale era con alcuni processi ETL per il server cognos IBM.
Kushal Paudyal,

1
volevo solo escluderlo lanciandolo attraverso qualsiasi script shell / batch che potrebbe passare un -Duser.timezonevalore
matt b

Risposte:


220

È possibile passare a JVM questo parametro

-Duser.timezone

Per esempio

-Duser.timezone=Europe/Sofia

e questo dovrebbe fare il trucco. L'impostazione della variabile d'ambiente TZ fa anche il trucco su Linux.


Abbiamo dovuto utilizzare lo strumento di aggiornamento del fuso orario DST JDK - 1.3.25 (tzupdater) e quindi modificare il parametro JVM come suggerito e alla fine ci siamo liberati del problema. A proposito, le informazioni sul fuso orario sono archiviate da Windows in alcuni registri. Il programma di aggiornamento che ho usato ha aggiornato anche i valori del registro.
Kushal Paudyal,

1
Sto cercando di avviare la mia JVM usando questo parametro, ma sembra che non ci siano cambiamenti ... Se voglio iniziare su UTC cosa devo usare come parametro !?
rafa.ferreira,

Nella mia applicazione sto cambiando alcune posizioni e ottengo i fusi orari di tali posizioni. Utilizzando il fuso orario che sto elaborando ulteriormente, ma quando l'applicazione viene avviata per la prima volta, ottengo i valori corretti. Quando cambio TimeZone e imposto il nuovo fuso orario come fuso orario predefinito, non ottengo i valori corretti. Qual è il problema? Come cambiare esattamente il fuso orario. Sto cambiando il fuso orario usando TimeZone.setDefault (TimeZone.getTimeZone ("my_time_zone"));
Dray il

2
Un elenco dei fusi orari per TZ è qui: en.wikipedia.org/wiki/List_of_tz_database_time_zones . L'uso del nome del fuso orario è migliore dell'offset perché gestirà l'ora legale.
Brian,

65

Puoi anche impostare il fuso orario predefinito nel tuo codice usando il seguente codice.

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

Alla tua

 TimeZone.setDefault(TimeZone.getTimeZone("Europe/Sofia"));

1
"Nota che non voglio impostare il fuso orario dall'applicazione."
AbVog,

22

La risposta accettata sopra:

-Duser.timezone="Europe/Sofia" 

Non ha funzionato esattamente per me. Sono stato in grado di modificare correttamente il mio fuso orario solo quando non avevo le virgolette intorno ai parametri:

-Duser.timezone=Europe/Sofia

2
Sono d'accordo. Ho modificato la risposta originale per rimuovere le virgolette.
GaZ,

1
Questo dipende dalla shell usata.
vadipp,

10

Su Windows 7 e per JDK6, ho dovuto aggiungere -Duser.timezone="Europe/Sofia"la variabile di sistema JAVA_TOOL_OPTIONS in "Risorse del computer => Proprietà => Impostazioni di sistema avanzate => Variabili di ambiente".

Se hai già impostato altre proprietà per JAVA_TOOL_OPTIONSaggiungere semplicemente uno spazio e quindi inserire la stringa di proprietà.


5

Due opzioni che non credo fossero trattate nelle altre risposte:

Evita il bisogno

Qualunque cosa tu faccia per impostare il fuso orario predefinito di JVM, è molto difficile assicurarsi che nessun altro lo imposti diversamente. Può essere impostato in qualsiasi momento senza preavviso da un'altra parte del programma o da un altro programma in esecuzione nella stessa JVM. Quindi nelle tue operazioni temporali sii esplicito su quale fuso orario vuoi e saprai sempre cosa ottieni indipendentemente dall'impostazione JVM. Esempio:

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

Esempio di output:

2018-10-11T14: 59: 16,742,02 mila + 05: 00 [Asia / Dushanbe]

System.setProperty

Per molti scopi, ciò che segue non sarà il modo preferito e può certamente essere utilizzato in modo improprio. Per i programmi "buttare via" a volte lo trovo pratico. Puoi anche impostare una proprietà di sistema da Java:

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

Questo appena stampato:

2018-10-11T21: 03: 12,218,959 mila + 11: 00 [Australia / Tasmania]

Se si desidera la convalida della stringa che si sta passando, utilizzare:

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

4

Se stai usando Maven :

mvn -Dexec.args="-Duser.timezone=Europe/Sofia ....."

mvn spring-boot:run -Drun.jvmArguments="-Duser.timezone=UTC"per Spring Boot v1.
Chloe,

0

In win7, se si desidera impostare il fuso orario corretto come parametro in JRE, è necessario modificare il file deployment.propertiesmemorizzato nel percorso c:\users\%username%\appdata\locallow\sun\java\deploymentaggiungendo la stringa deployment.javaws.jre.1.args=-Duser.timezone\=my_time_zone


L'ho provato e non funziona (jvm eseguito da Intellij)
kumetix,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.