Jak prawidłowo ustawić strefę czasową JVM

141

Próbuję uruchomić program Java, ale używa on domyślnej strefy czasowej GMT zamiast strefy czasowej zdefiniowanej przez system operacyjny. Moja wersja JDK to 1.5, a system operacyjny to Windows Server Enterprise (2007)

Windows ma określoną centralną strefę czasową, ale kiedy uruchamiam następujący program, podaje mi czas 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());
    }
}

Oto wynik

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

Pamiętaj, że nie chcę ustawiać strefy czasowej z poziomu aplikacji. Chcę, aby strefa czasowa używana przez maszynę JVM była określona w systemie operacyjnym. (Nie znajduję tego problemu na innych serwerach, które mają wersję 1.4 JDK i Microsoft Server 2003).

Wszelkie myśli byłyby bardzo mile widziane.

Kushal Paudyal
źródło
1
Hm, to dziwne. Wygląda na błąd JVM / OS lub dziwną błędną konfigurację.
Michael Borgwardt
jak wywołujesz DateTestzajęcia?
Matt b
@matt b: kompiluję i wywołuję DateTest z wiersza poleceń systemu Windows. Ale to tylko klasa testowa. Pierwotny problem dotyczył jakiegoś procesu ETL dla serwera IBM cognos.
Kushal Paudyal
1
chciałem tylko wykluczyć uruchamianie go za pomocą jakichkolwiek skryptów powłoki / wsadowych, które mogą przekazywać -Duser.timezonewartość
mat b

Odpowiedzi:

220

Możesz przekazać JVM ten parametr

-Duser.timezone

Na przykład

-Duser.timezone=Europe/Sofia

i to powinno załatwić sprawę. Ustawienie zmiennej środowiskowej TZ również załatwia sprawę w systemie Linux.

Bozhidar Batsov
źródło
Musieliśmy użyć narzędzia do aktualizacji strefy czasowej JDK DST - 1.3.25 (tzupdater), a następnie zmienić parametr JVM zgodnie z sugestią i ostatecznie pozbyliśmy się problemu. Nawiasem mówiąc, informacje o strefie czasowej są przechowywane przez system Windows w jakimś rejestrze. Aktualizator, którego użyłem, zaktualizował również wartości rejestru.
Kushal Paudyal
1
Próbuję uruchomić maszynę JVM przy użyciu tego parametru, ale wydaje mi się, że nic się nie zmieniło ... Jeśli chcę zacząć w UTC, co powinienem użyć jako parametru !?
rafa.ferreira
W mojej aplikacji zmieniam niektóre lokalizacje i pobieram strefy czasowe tych lokalizacji. Korzystając ze strefy czasowej przetwarzam dalej, ale gdy aplikacja uruchamia się po raz pierwszy, otrzymuję prawidłowe wartości. Kiedy zmieniam strefę czasową i ustawiam nową strefę czasową jako domyślną, nie otrzymuję prawidłowych wartości. Na czym polega problem? Jak dokładnie zmienić strefę czasową. Zmieniam strefę czasową za pomocą TimeZone.setDefault (TimeZone.getTimeZone ("my_time_zone"));
Dray
2
Lista stref czasowych dla TZ znajduje się tutaj: en.wikipedia.org/wiki/List_of_tz_database_time_zones . Użycie nazwy strefy czasowej jest lepsze niż przesunięcie, ponieważ będzie obsługiwać czas letni.
Brian
65

Możesz również ustawić domyślną strefę czasową w swoim kodzie, używając następującego kodu.

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

Do Twojego

 TimeZone.setDefault(TimeZone.getTimeZone("Europe/Sofia"));
Ali786
źródło
1
„Pamiętaj, że nie chcę ustawiać strefy czasowej z poziomu aplikacji”.
AbVog
22

Przyjęta odpowiedź powyżej:

-Duser.timezone="Europe/Sofia" 

Nie działało dla mnie dokładnie. Mogłem pomyślnie zmienić strefę czasową tylko wtedy, gdy nie miałem cudzysłowów wokół parametrów:

-Duser.timezone=Europe/Sofia
WN4yhihiY
źródło
2
Zgadzam się. Zredagowałem oryginalną odpowiedź, aby usunąć cytaty.
GaZ
1
To zależy od użytej powłoki.
vadipp
10

W systemie Windows 7 i JDK6 musiałem dodać -Duser.timezone="Europe/Sofia"do JAVA_TOOL_OPTIONS zmiennej systemowej znajdującej się w „Mój komputer => Właściwości => Zaawansowane ustawienia systemu => Zmienne środowiskowe”.

Jeśli masz już ustawioną inną właściwość, JAVA_TOOL_OPTIONSwystarczy dołączyć spację, a następnie wstawić ciąg znaków właściwości.

VolkanT
źródło
5

Dwie opcje, których nie sądzę, zostały uwzględnione w innych odpowiedziach:

Unikaj potrzeby

Cokolwiek robisz, aby ustawić domyślną strefę czasową maszyny JVM, bardzo trudno jest się upewnić, że nikt inny nie ustawi jej inaczej. Można go ustawić w dowolnym momencie bez powiadomienia z innej części programu lub innego programu działającego w tej samej JVM. Tak więc w operacjach czasowych jasno określ, którą strefę czasową chcesz, a zawsze będziesz wiedział, co otrzymujesz, niezależnie od ustawienia JVM. Przykład:

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

Przykładowe dane wyjściowe:

2018-10-11T14: 59: 16.742020 + 05: 00 [Azja / Duszanbe]

System.setProperty

Z wielu powodów poniższy sposób nie będzie preferowany iz pewnością można go nadużyć. W przypadku programów „do wyrzucenia” czasami wydaje mi się to praktyczne. Możesz również ustawić właściwość systemową z poziomu Java:

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

To właśnie zostało wydrukowane:

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

Jeśli chcesz sprawdzić poprawność przekazywanego ciągu, użyj:

        System.setProperty("user.timezone", ZoneId.of("Australia/Tasmania").getId());
Ole VV
źródło
4

Jeśli używasz Maven :

mvn -Dexec.args="-Duser.timezone=Europe/Sofia ....."
MichalSv
źródło
mvn spring-boot:run -Drun.jvmArguments="-Duser.timezone=UTC"dla Spring Boot v1.
Chloe
0

W win7, jeśli chcesz ustawić odpowiednią strefę czasową jako parametr w JRE, musisz edytować plik deployment.propertiesprzechowywany w ścieżce c:\users\%username%\appdata\locallow\sun\java\deploymentdodając ciąg deployment.javaws.jre.1.args=-Duser.timezone\=my_time_zone

Dave
źródło
Próbowałem i nie działa (jvm uruchamiany z wewnątrz intellij)
kumetix