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_York
或Europe/Paris
)。 避免使用简写(如CET
或CEST
),因为它们不明确而不是标准 。
您可以通过调用ZoneId.getAvailableZoneIds()
来获取可用时区列表(并select最适合您的系统的时区ZoneId.getAvailableZoneIds()
。
看着grepcode的源代码,他们最终执行完全相同的方法,结果相同。 Clock.systemDefaultZone()
调用ZoneId.systemDefault()
,它返回TimeZone.getDefault().toZoneId()
: