Comment définir correctement un fuseau horaire JVM

141

J'essaie d'exécuter un programme Java, mais il prend un fuseau horaire GMT par défaut au lieu d'un fuseau horaire défini par le système d'exploitation. Ma version JDK est 1.5 et le système d'exploitation est Windows Server Enterprise (2007)

Windows a un fuseau horaire central spécifié, mais lorsque j'exécute le programme suivant, il me donne une heure 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());
    }
}

Voici la sortie

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

Veuillez noter que je ne souhaite pas définir le fuseau horaire depuis l'application. Je veux que le fuseau horaire utilisé par JVM soit celui spécifié dans le système d'exploitation. (Je ne trouve pas ce problème avec d'autres serveurs qui ont la version 1.4 de JDK et Microsoft Server 2003).

Toutes les pensées seraient très appréciées.

Kushal Paudyal
la source
1
Hm, c'est étrange. On dirait un bogue JVM / OS ou une mauvaise configuration étrange.
Michael Borgwardt
comment invoquez-vous la DateTestclasse?
matt b
@matt b: Je compile et j'appelle DateTest à partir de l'invite de commande Windows. Mais ce n'est qu'une classe de test. Le problème d'origine était lié à un processus ETL pour le serveur IBM Cognos.
Kushal Paudyal
1
voulait juste exclure de le lancer via des scripts shell / batch qui pourraient transmettre une -Duser.timezonevaleur
matt b

Réponses:

220

Vous pouvez passer la JVM ce paramètre

-Duser.timezone

Par exemple

-Duser.timezone=Europe/Sofia

et cela devrait faire l'affaire. La définition de la variable d'environnement TZ fait également l'affaire sous Linux.

Bozhidar Batsov
la source
Nous avons dû utiliser l'outil de mise à jour du fuseau horaire JDK DST - 1.3.25 (tzupdater), puis modifier le paramètre JVM comme vous l'aviez suggéré et nous avons finalement résolu le problème. À propos, les informations de fuseau horaire sont stockées par Windows dans un registre. Le programme de mise à jour que j'ai utilisé a également mis à jour les valeurs de registre.
Kushal Paudyal
1
J'essaie de démarrer ma JVM en utilisant ce paramètre, mais semble n'avoir aucun changement ... Si je veux démarrer à UTC, que dois-je utiliser comme paramètre !?
rafa.ferreira
Dans mon application, je change certains emplacements et j'obtiens les fuseaux horaires de ces emplacements.En utilisant le fuseau horaire, je continue de traiter.Mais lorsque l'application démarre pour la première fois, j'obtiens des valeurs correctes. Lorsque je change de fuseau horaire et que je définis le nouveau fuseau horaire comme fuseau horaire par défaut, je n'obtiens pas les valeurs correctes. Quel est le problème? Comment changer le fuseau horaire exactement. Je change le fuseau horaire en utilisant TimeZone.setDefault (TimeZone.getTimeZone ("my_time_zone"));
Dray
2
Une liste des fuseaux horaires pour TZ est ici: en.wikipedia.org/wiki/List_of_tz_database_time_zones . L'utilisation du nom du fuseau horaire est meilleure que le décalage car il gérera l'heure d'été.
Brian
65

Vous pouvez également définir le fuseau horaire par défaut dans votre code à l'aide du code suivant.

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

A la votre

 TimeZone.setDefault(TimeZone.getTimeZone("Europe/Sofia"));
Ali786
la source
1
"Veuillez noter que je ne souhaite pas définir le fuseau horaire depuis l'application."
AbVog
22

La réponse acceptée ci-dessus:

-Duser.timezone="Europe/Sofia" 

Cela n'a pas fonctionné pour moi exactement. Je n'ai réussi à changer mon fuseau horaire que lorsque je n'avais pas de guillemets autour des paramètres:

-Duser.timezone=Europe/Sofia
WN4yhihiY
la source
2
Je suis d'accord. J'ai modifié la réponse originale pour supprimer les citations.
GaZ
1
Cela dépend du shell utilisé.
vadipp
10

Sur Windows 7 et pour JDK6, j'ai dû ajouter -Duser.timezone="Europe/Sofia"aux JAVA_TOOL_OPTIONS variable système située sous "Mon ordinateur => Propriétés => Paramètres système avancés => Variables d'environnement".

Si vous avez déjà une autre propriété définie pour JAVA_TOOL_OPTIONSsimplement ajouter un espace, puis insérez votre chaîne de propriété.

VolkanT
la source
5

Deux options qui, à mon avis, n'étaient pas couvertes dans les autres réponses:

Évitez le besoin

Quoi que vous fassiez pour définir le fuseau horaire par défaut de la JVM, il est très difficile de s'assurer que personne d'autre ne le définit différemment. Il peut être défini à tout moment sans préavis depuis une autre partie de votre programme ou depuis un autre programme s'exécutant dans la même JVM. Ainsi, dans vos opérations de temps, soyez explicite sur le fuseau horaire souhaité, et vous saurez toujours ce que vous obtenez indépendamment du paramètre JVM. Exemple:

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

Exemple de sortie:

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

System.setProperty

À de nombreuses fins, ce qui suit ne sera pas la méthode préférée, et il peut certainement être mal utilisé. Pour les programmes «à jeter», je trouve parfois cela pratique. Vous pouvez également définir une propriété système à partir de Java:

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

Cela vient d'imprimer:

2018-10-11T21: 03: 12.218959 + 11: 00 [Australie / Tasmanie]

Si vous souhaitez valider la chaîne que vous passez, utilisez:

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

Si vous utilisez Maven :

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

Dans win7, si vous souhaitez définir le fuseau horaire correct comme paramètre dans JRE, vous devez éditer le fichier deployment.propertiesstocké dans path en c:\users\%username%\appdata\locallow\sun\java\deploymentajoutant la chaîne deployment.javaws.jre.1.args=-Duser.timezone\=my_time_zone

Dave
la source
Je l'ai essayé et cela ne fonctionne pas (jvm exécuté à partir d'intellij)
kumetix