java.time.Clock.systemDefaultZone().getZone() 与 java.util.TimeZone.getDefault().toZoneId() 之间有什么区别?
Any difference between java.time.Clock.systemDefaultZone().getZone() vs java.util.TimeZone.getDefault().toZoneId()?
鉴于java.time.Clock.systemDefaultZone().getZone()
和java.util.TimeZone.getDefault().toZoneId()
return输出相同,两者之间有什么区别吗?
比如这段代码
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());
}
}
returns 这个输出
Clock.systemDefaultZone().getZone() : Europe/Paris
TimeZone.getDefault().toZoneId() : Europe/Paris
查看 grepcode 上的源代码,他们最终执行完全相同的方法,导致相同的结果。 Clock.systemDefaultZone()
调用 ZoneId.systemDefault()
,其中 returns TimeZone.getDefault().toZoneId()
:
两者 return 都是 JVM 的默认时区(最后,Clock
调用 TimeZone.getDefault()
,如 中所述),但不能保证所有调用总是 return 相同的值每次。
那是因为可以更改默认时区:
- JVM 所在的系统 运行ning 可以更改其配置。例如,在 Windows 机器中,这个 information is read from the registry,而在 Linux 中,它从
/etc/localtime
(通常是 link 到 [=14= 中的特定文件) ]) 或另一个类似的文件夹(每个 version/distribution 可能有所不同),或者通过设置 TZ
环境变量。如果此系统配置更改并重新启动 JVM,您的代码突然开始 returning 不同的值
- JVM can be configured to use a different timezone,无论 OS 的配置如何。一个例子是 maintanance/infrastructure 团队更改了此配置(有意或无意,通常没有告诉开发人员...),然后您的代码不再 return 相同的值(以及所有内容这取决于时区会突然中断)
您的应用程序(或另一个应用程序 运行使用相同的 JVM)调用 TimeZone.setDefault()
method。这将影响 运行 在同一 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());
输出将是:
Europe/London
America/New_York
UTC
请注意默认时区在 运行 时是多么容易更改,所有后续获取它的调用都会受到影响。如果您调用 Clock.systemDefaultZone().getZone()
或 TimeZone.getDefault().toZoneId()
,也会发生同样的情况,因为两者都使用默认时区。
由于这会更改 JVM 的默认时区,因此 运行 同一 JVM 中的所有应用程序都将受其影响。这可能会导致难以调试的意外错误。
虽然使用默认时区的方法很方便,但您必须检查您的代码如何依赖它以及如果时区更改会如何影响它。
如果你不想依赖于默认值,理想的是使用特定的时区,例如ZoneId.of("Europe/Paris")
。始终首选 IANA timezones names(始终采用 Region/City
格式,例如 America/New_York
或 Europe/Paris
)。
避免使用短缩写(如 CET
或 CEST
),因为它们是 ambiguous and not standard.
您可以通过调用 ZoneId.getAvailableZoneIds()
.
获取可用时区列表(并选择最适合您的系统的时区)
鉴于java.time.Clock.systemDefaultZone().getZone()
和java.util.TimeZone.getDefault().toZoneId()
return输出相同,两者之间有什么区别吗?
比如这段代码
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());
}
}
returns 这个输出
Clock.systemDefaultZone().getZone() : Europe/Paris
TimeZone.getDefault().toZoneId() : Europe/Paris
查看 grepcode 上的源代码,他们最终执行完全相同的方法,导致相同的结果。 Clock.systemDefaultZone()
调用 ZoneId.systemDefault()
,其中 returns TimeZone.getDefault().toZoneId()
:
两者 return 都是 JVM 的默认时区(最后,Clock
调用 TimeZone.getDefault()
,如
那是因为可以更改默认时区:
- JVM 所在的系统 运行ning 可以更改其配置。例如,在 Windows 机器中,这个 information is read from the registry,而在 Linux 中,它从
/etc/localtime
(通常是 link 到 [=14= 中的特定文件) ]) 或另一个类似的文件夹(每个 version/distribution 可能有所不同),或者通过设置TZ
环境变量。如果此系统配置更改并重新启动 JVM,您的代码突然开始 returning 不同的值 - JVM can be configured to use a different timezone,无论 OS 的配置如何。一个例子是 maintanance/infrastructure 团队更改了此配置(有意或无意,通常没有告诉开发人员...),然后您的代码不再 return 相同的值(以及所有内容这取决于时区会突然中断)
您的应用程序(或另一个应用程序 运行使用相同的 JVM)调用
TimeZone.setDefault()
method。这将影响 运行 在同一 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());
输出将是:
Europe/London
America/New_York
UTC
请注意默认时区在 运行 时是多么容易更改,所有后续获取它的调用都会受到影响。如果您调用 Clock.systemDefaultZone().getZone()
或 TimeZone.getDefault().toZoneId()
,也会发生同样的情况,因为两者都使用默认时区。
由于这会更改 JVM 的默认时区,因此 运行 同一 JVM 中的所有应用程序都将受其影响。这可能会导致难以调试的意外错误。
虽然使用默认时区的方法很方便,但您必须检查您的代码如何依赖它以及如果时区更改会如何影响它。
如果你不想依赖于默认值,理想的是使用特定的时区,例如ZoneId.of("Europe/Paris")
。始终首选 IANA timezones names(始终采用 Region/City
格式,例如 America/New_York
或 Europe/Paris
)。
避免使用短缩写(如 CET
或 CEST
),因为它们是 ambiguous and not standard.
您可以通过调用 ZoneId.getAvailableZoneIds()
.