Qualquer diferença entre java.time.Clock.systemDefaultZone (). GetZone () vs java.util.TimeZone.getDefault (). ToZoneId ()?

Existe alguma diferença entre os dois, dado que ambos java.time.Clock.systemDefaultZone().getZone() e java.util.TimeZone.getDefault().toZoneId() retornam a mesma saída.

Por exemplo, este código

 import java.time.Clock; import java.util.TimeZone; public class Main { public static void main(String[] args) { System.out.println("Clock.systemDefaultZone().getZone() : " + Clock.systemDefaultZone().getZone()); System.out.println("TimeZone.getDefault().toZoneId() : " + TimeZone.getDefault().toZoneId()); } } 

retorna esta saída

 Clock.systemDefaultZone().getZone() : Europe/Paris TimeZone.getDefault().toZoneId() : Europe/Paris 

Ambos retornam o fuso horário padrão da JVM (no final, Clock chama TimeZone.getDefault() , como explicado na resposta de @Kiskae ), mas não é garantido que todas as chamadas sempre retornarão o mesmo valor toda vez .

Isso porque o fuso horário padrão pode ser alterado:

  • o sistema no qual a JVM está sendo executada pode alterar sua configuração. Em máquinas Windows, por exemplo, essas informações são lidas do registro , enquanto no Linux elas são obtidas de /etc/localtime (geralmente um link para um arquivo específico em /usr/share/zoneinfo ) ou outra pasta similar (pode variar em cada versão / distribuição) ou definindo a variável de ambiente TZ . Se essa configuração do sistema a alterar e a JVM for reiniciada, de repente, seu código começará a retornar valores diferentes
  • a JVM pode ser configurada para usar um fuso horário diferente , independentemente da configuração do sistema operacional. Um exemplo é quando a equipe de manutenção / infraestrutura muda essa configuração (de propósito ou por acidente e geralmente sem avisar os desenvolvedores …) e então seu código não retorna mais os mesmos valores (e tudo o que depende do fuso horário de repente quebrar)
  • seu aplicativo (ou outro aplicativo executando a mesma JVM) chama o método TimeZone.setDefault() . Isso afetará todos os aplicativos em execução na mesma JVM, em tempo de execução , portanto, se você executar este código:

     TimeZone.setDefault(TimeZone.getTimeZone("Europe/London")); System.out.println(ZoneId.systemDefault()); TimeZone.setDefault(TimeZone.getTimeZone("America/New_York")); System.out.println(ZoneId.systemDefault()); TimeZone.setDefault(TimeZone.getTimeZone("UTC")); System.out.println(ZoneId.systemDefault()); 

A saída será:

Europa / Londres
América / New_York
UTC

Observe com que facilidade o fuso horário padrão é alterado no tempo de execução e todas as chamadas subseqüentes para obtê-lo são afetadas. O mesmo acontecerá se você chamar Clock.systemDefaultZone().getZone() ou TimeZone.getDefault().toZoneId() , porque ambos usam o fuso horário padrão.

Como isso altera o fuso horário padrão da JVM, todos os aplicativos em execução na mesma JVM serão afetados por ela. Isso pode levar a erros inesperados que são difíceis de depurar.

Embora os methods que usam o fuso horário padrão sejam convenientes, você deve verificar como seu código depende dele e como ele pode ser afetado se a zona for alterada.

Se você não quiser depender do padrão, o ideal é usar um fuso horário específico, como ZoneId.of("Europe/Paris") . Sempre prefira nomes de fusos horários da IANA (sempre no formato Region/City , como America/New_York ou Europe/Paris ). Evite usar as abreviaturas curtas (como CET ou CEST ) porque elas são ambíguas e não padrão .

Você pode obter uma lista de fusos horários disponíveis (e escolher aquele que melhor se ajusta ao seu sistema) chamando ZoneId.getAvailableZoneIds() .

Olhando para o código-fonte no grepcode, eles acabam executando exatamente os mesmos methods, resultando no mesmo resultado. Clock.systemDefaultZone() chama ZoneId.systemDefault() , que retorna TimeZone.getDefault().toZoneId() :

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/time/ZoneId.java#ZoneId.systemDefault%28%29