java.time.Clock.systemDefaultZone().getZone() 和 java.util.TimeZone.getDefault().toZoneId() 有什么区别?(涉及IT技术)

3

鉴于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

1
主要区别在于TimeZone已经过时(尽管尚未正式弃用),而Clock是现代的。 - Ole V.V.
2个回答

5

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

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

  • the system where the JVM is running can change its configuration. In Windows machines, for example, this information is read from the registry, while in Linux it gets from /etc/localtime (usually a link to a specific file in /usr/share/zoneinfo) or another similar folder (it can vary in each version/distribution), or by setting the TZ environment variable. If this system configuration changes it and the JVM is restarted, suddenly your code starts returning different values
  • the JVM can be configured to use a different timezone, regardless of OS's config. One example is when the maintanance/infrastructure team changes this configuration (on purpose or by accident, and usually without telling the developers...) and then your code doesn't return the same values anymore (and everything that depends on the timezone will suddenly break)
  • your application (or another application running the same JVM) calls TimeZone.setDefault() method. This will affect all the applications running in the same JVM, at runtime, so if you run this code:

    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中运行的所有应用程序都会受到影响。这可能会导致难以调试的意外错误。
虽然使用默认时区的方法很方便,但必须检查代码如何依赖它以及如果时区更改会受到影响。
如果不想依赖默认值,则理想的方法是使用特定的时区,例如 ZoneId.of("Europe/Paris")。始终优先使用IANA时区名称(始终以格式 Region / City ,如 America/New_YorkEurope/Paris )。 避免使用短缩写(例如 CETCEST),因为它们是不明确和不标准的
您可以通过调用 ZoneId.getAvailableZoneIds() 获取可用时区列表(并选择最适合您系统的时区)。

4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接