java.time.Clock.systemDefaultZone().getZone()和java.util.TimeZone.getDefault().toZoneId()之间有什么区别吗?

java.time.Clock.systemDefaultZone().getZone()和java.util.TimeZone.getDefault().toZoneId()之间有什么区别吗?,java,java-8,timezone,java-time,Java,Java 8,Timezone,Java Time,如果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.

如果
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

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


都返回JVM的默认时区(最后,
Clock
调用
timezone.getDefault()
,如中所述),但不能保证所有调用每次都返回相同的值

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

  • JVM运行的系统可以更改其配置。例如,在Windows机器中,当在Linux中时,它从
    /etc/localtime
    (通常是指向
    /usr/share/zoneinfo
    中特定文件的链接)或其他类似文件夹(在每个版本/发行版中可能有所不同)或通过设置
    TZ
    环境变量来获取。如果这个系统配置改变了它,JVM被重新启动,那么代码会突然返回不同的值
  • JVM,无论操作系统的配置如何。一个例子是,当维护/基础设施团队更改此配置时(有意或无意,通常不告诉开发人员…),然后您的代码不再返回相同的值(并且依赖于时区的所有内容都将突然中断)
  • 您的应用程序(或运行相同JVM的另一个应用程序)调用。这将影响在运行时运行在同一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());
    
输出将是:

欧洲/伦敦
美国/纽约
UTC

请注意,在运行时更改默认时区是多么容易,并且所有后续获取该时区的调用都会受到影响。如果调用
Clock.systemDefaultZone().getZone()
TimeZone.getDefault().toZoneId()
,也会发生同样的情况,因为两者都使用默认时区

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

虽然使用默认时区的方法很方便,但您必须检查代码如何依赖于它,以及如果时区更改,它会受到什么影响

如果您不想依赖默认设置,理想的做法是使用特定的时区,例如
ZoneId.of(“Europe/Paris”)
。始终首选(始终采用
地区/城市
格式,如
美国/纽约
欧洲/巴黎
)。 避免使用短缩写(如
CET
CEST
),因为它们是


通过调用
ZoneId.getAvailableZoneIds()

可以获得可用时区的列表(并选择最适合您的系统的时区)。主要区别在于
时区已过时(尽管尚未正式弃用),而
时钟则是现代的。