Como definir um fuso horário da JVM corretamente

141

Estou tentando executar um programa Java, mas está tomando um fuso horário GMT padrão em vez de um fuso horário definido pelo SO. Minha versão do JDK é 1.5 e o sistema operacional é o Windows Server Enterprise (2007)

O Windows possui um fuso horário Central especificado, mas quando executo o programa a seguir, ele fornece um horário 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());
    }
}

Aqui está a saída

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

Observe que não desejo definir o fuso horário do aplicativo. Desejo que o fuso horário usado pela JVM seja o especificado no SO. (Não estou encontrando esses problemas com outros servidores com a versão 1.4 do JDK e Microsoft Server 2003).

Qualquer pensamento seria muito apreciado.

Kushal Paudyal
fonte
1
Hum, isso é estranho. Parece um bug da JVM / OS ou alguma configuração estranha.
Michael Borgwardt
como você está invocando a DateTestclasse?
mate b
@matt b: Estou compilando e chamando o DateTest no prompt de comando do Windows. Mas isso é apenas uma classe de teste. O problema original estava com algum processo de ETL para o servidor IBM cognos.
Kushal Paudyal 22/03
1
só queria descartar lançá-lo através de todos os scripts shell / lote que pode estar passando ao longo de um -Duser.timezonevalor
matt b

Respostas:

220

Você pode passar a JVM neste parâmetro

-Duser.timezone

Por exemplo

-Duser.timezone=Europe/Sofia

e isso deve fazer o truque. Definir a variável de ambiente TZ também faz o truque no Linux.

Bozhidar Batsov
fonte
Tivemos que usar a Ferramenta de Atualização do Fuso Horário do JDK DST - 1.3.25 (tzupdater) e, em seguida, alterar o parâmetro JVM conforme sugerido, e finalmente nos livramos do problema. A propósito, as informações do fuso horário são armazenadas pelo Windows em algum registro. O atualizador que eu usei também atualizou os valores do registro.
Kushal Paudyal 25/03
1
Estou tentando inicializar minha JVM usando esse parâmetro, mas parece não ter alterações ... Se eu quiser iniciar no UTC, o que devo usar como parâmetro !?
Rafa.ferreira
No meu aplicativo, estou alterando alguns locais e obtendo fusos horários desses locais. Usando o fuso horário, estou processando mais. Mas, quando o aplicativo inicia pela primeira vez, estou obtendo valores corretos. Quando altero o fuso horário e defino o novo fuso horário como fuso horário padrão, não estou obtendo os valores corretos. Qual é o problema? Como alterar exatamente o fuso horário. Estou alterando o fuso horário usando TimeZone.setDefault (TimeZone.getTimeZone ("my_time_zone"));
Dray
2
Uma lista dos fusos horários para TZ está aqui: en.wikipedia.org/wiki/List_of_tz_database_time_zones . O uso do nome do fuso horário é melhor que o deslocamento, pois ele administra o horário de verão.
187 Brian
65

Você também pode definir o fuso horário padrão no seu código usando o código a seguir.

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

Para o seu

 TimeZone.setDefault(TimeZone.getTimeZone("Europe/Sofia"));
Ali786
fonte
1
"Por favor, note que não quero definir o fuso horário do aplicativo."
AbVog 2/17/17
22

A resposta aceita acima:

-Duser.timezone="Europe/Sofia" 

Não funcionou exatamente para mim. Eu só consegui alterar meu fuso horário com sucesso quando não tinha aspas nos parâmetros:

-Duser.timezone=Europe/Sofia
WN4yhihiY
fonte
2
Concordo. Eu editei a resposta original para remover as aspas.
GaZ 17/07
1
Isso depende do shell usado.
vadipp
10

No Windows 7 e no JDK6, tive que adicionar -Duser.timezone="Europe/Sofia"à variável de sistema JAVA_TOOL_OPTIONS localizada em "Meu computador => Propriedades => Configurações avançadas do sistema => Variáveis ​​de ambiente".

Se você já tiver alguma outra propriedade definida, JAVA_TOOL_OPTIONSbasta anexar um espaço e, em seguida, insira sua sequência de propriedades.

VolkanT
fonte
5

Duas opções que acho que não foram abordadas nas outras respostas:

Evite a necessidade

Tudo o que você faz para definir o fuso horário padrão da JVM, é muito difícil garantir que ninguém mais o defina de maneira diferente. Pode ser definido a qualquer momento, sem aviso prévio de outra parte do seu programa ou de outro programa em execução na mesma JVM. Portanto, em suas operações de horário, seja explícito sobre qual fuso horário você deseja e sempre saberá o que obtém independentemente da configuração da JVM. Exemplo:

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

Exemplo de saída:

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

System.setProperty

Para muitos propósitos, o seguinte não será o caminho preferido e certamente pode ser mal utilizado. Para programas de "jogar fora", às vezes acho prático. Você também pode definir uma propriedade do sistema no Java:

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

Isso acabou de ser impresso:

2018-10-11T21: 03: 12.218959 + 11:00 [Austrália / Tasmânia]

Se você deseja validar a string que está passando, use:

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

Se você estiver usando o Maven :

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

No win7, se você quiser definir o fuso horário correto como um parâmetro no JRE, precisará editar o arquivo deployment.propertiesarmazenado no caminho, c:\users\%username%\appdata\locallow\sun\java\deploymentadicionando a sequência deployment.javaws.jre.1.args=-Duser.timezone\=my_time_zone

Dave
fonte
Eu tentei e ele não funciona (JVM executada de dentro intellij)
kumetix