java.time.Clock.systemDefaultZone()。getZone()与java.util.TimeZone.getDefault()。toZoneId()之间的任何区别?

考虑到java.time.Clock.systemDefaultZone().getZone()java.util.TimeZone.getDefault().toZoneId()返回相同的输出,两者之间是否有区别。

例如这个代码

 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()); } } 

返回这个输出

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

两者都返回JVM的默认时区(最后, Clock调用TimeZone.getDefault() ,如@ Kiskae的答案中所述 ),但不能保证所有的调用总是 每次 返回相同的值。

这是因为默认时区可以更改:

  • 运行JVM的系统可以更改其configuration。 例如,在Windows计算机中,这些信息是从registry中读取的 ,而在Linux中则是从/etc/localtime (通常是指向/usr/share/zoneinfo特定文件的链接)或其他类似文件夹每个版本/分发),或者通过设置TZ环境variables。 如果这个系统configuration改变了它,并且JVM重新启动,突然你的代码开始返回不同的值
  • 可以将 JVM configuration为使用不同的时区 ,而不pipe操作系统的configuration如何。 一个例子就是当保养/基础设施团队改变了这个configuration(有意或无意,而且通常没有告诉开发者……),然后你的代码不再返回相同的值(并且所有依赖于时区的东西都会突然中断)
  • 您的应用程序(或运行相同的JVM的另一个应用程序)调用TimeZone.setDefault()方法 。 这将影响运行时在同一个JVM 中运行的所有应用程序,所以如果你运行这个代码:

     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()); 

输出将是:

欧洲/伦敦
美国/纽约
世界标准时间

注意默认时区在运行时很容易改变,并且所有后续的调用都会受到影响。 如果您调用Clock.systemDefaultZone().getZone()TimeZone.getDefault().toZoneId() ,则会发生同样的情况,因为它们都使用默认的时区。

由于这会更改JVM的默认时区,所以在同一个JVM中运行的所有应用程序都将受其影响。 这可能会导致难以debugging的意外错误。

尽pipe使用默认时区的方法很方便,但您必须检查代码如何依赖于它,以及如果区域更改,如何影响代码。

如果您不想依赖默认设置,理想情况是使用特定的时区,如ZoneId.of("Europe/Paris") 。 始终更喜欢IANA时区名称 (始终以Region/City的格式,如America/New_YorkEurope/Paris )。 避免使用简写(如CETCEST ),因为它们不明确而不是标准 。

您可以通过调用ZoneId.getAvailableZoneIds()来获取可用时区列表(并select最适合您的系统的时区ZoneId.getAvailableZoneIds()

看着grepcode的源代码,他们最终执行完全相同的方法,结果相同。 Clock.systemDefaultZone()调用ZoneId.systemDefault() ,它返回TimeZone.getDefault().toZoneId()

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