java的clock指定时区_关于java:为什么Clock.systemDefaultZone()。instant()返回的时间与LocalTime.now()不同?...

为什么Clock.systemDefaultZone().instant()返回的时间不同于LocalTime.now()?

我知道LocalTime没有时区,但是它显示的是我的系统时钟(在计算机托盘上)显示的内容,对吗? 两者都"使用"默认时区(Europe/Moscow),因此时间应相同吗?

我的计算机时钟是Europe/Moscow,所以两者都应准确显示我的计算机时间?

System.out.println(Clock.systemDefaultZone().instant()); // 2018-03-19T10:10:27.156Z

System.out.println(Clock.systemDefaultZone().getZone()); // Europe/Moscow

System.out.println(LocalTime.now()); // 13:10:27.166

我猜Clock.systemDefaultZone().instant()只是UTC +0000

返回UTC时间的java.Clock中的Confusion可能重复,systemDefaultZone()

如此处所示,时钟基于UTC。 docs.oracle.com/javase/8/docs/api/java/time/

如果我没有发现问题,则.instant()返回的Instant不会处理任何时区信息。使用正确的时区(Clock.systemDefaultZone().getZone()返回的ZoneId),您可以从Instant(即时)中获取ZonedDateTime(它确实提供了时区信息)。

System.out.println(Clock.systemDefaultZone().instant());

System.out.println(Clock.systemDefaultZone().instant().atZone(Clock.systemDefaultZone().getZone()));

输出量

2018-03-19T10:30:47.032Z

2018-03-19T13:30:47.048+03:00[Europe/Moscow]

@AndyTurner谢谢,我已经编辑了我的答案。

只是为了让我更好地理解此类的用法,如果您说" .instant()的即时返回不处理任何时区信息",那么根据不同时区从时钟返回的即时之间有什么区别? (例如.systemDefaultZone()与.systemUTC())

@DodgyCodeException Instant相同,但是Clock.systemDefaultZone().getZone()返回EuropeMoscow,而Clock.systemUTC().getZone()返回Z(对于UTC +0000 /中央)。

时间

公共抽象类Clock扩展Object

时钟,用于使用时区访问当前时刻,日期和时间。

此类的实例用于查找当前时刻,可以使用存储的时区来解释当前时刻以查找当前日期和时间。这样,可以使用时钟代替System.currentTimeMillis()和TimeZone.getDefault()。

时钟的使用是可选的。所有关键日期时间类还具有now()工厂方法,该方法在默认时区使用系统时钟。这种抽象的主要目的是允许在需要时插入备用时钟。应用程序使用对象而不是静态方法来获取当前时间。这样可以简化测试。

应用程序的最佳实践是将Clock传递到需要当前时刻的任何方法中。依赖项注入框架是实现此目标的一种方法:

public class MyBean {

private Clock clock;  // dependency inject

...

public void process(LocalDate eventDate) {

if (eventDate.isBefore(LocalDate.now(clock)) {

...

}

}

}

这种方法允许在测试期间使用备用时钟,例如固定时钟或偏移时钟。

系统工厂方法基于最佳的可用系统时钟提供时钟。此时钟可以使用System.currentTimeMillis(),或者使用更高分辨率的时钟(如果有)。

实施要求:

必须小心实现此抽象类,以确保其他类正确运行。可以实例化的所有实现必须是最终的,不可变的并且是线程安全的。

定义了主体方法以允许引发异常。在正常使用中,不会抛出异常,但是一种可能的实现方式是从网络上的中央时间服务器获取时间。显然,在这种情况下,查找可能会失败,因此允许该方法引发异常。

从"时钟"返回的瞬间按忽略时长的秒数工作,如"即时"中所述。如果实现包装提供provides秒信息的源,则应使用一种机制来"平滑" the秒。 Java时标要求使用UTC-SLS,但是时钟实现可以选择它们在时标中的精确度,只要它们记录了它们的工作方式即可。因此,不需要实际执行UTC-SLS转换或以其他方式了解leap秒的实现。

实现应尽可能实现Serializable,并且必须记录它们是否支持序列化。

实施说明:

此处提供的时钟实现基于System.currentTimeMillis()。该方法几乎不能保证时钟的准确性。需要更精确时钟的应用程序必须使用其他外部时钟(例如NTP服务器)自己实现此抽象类。

以来:

1.8

java.?time.?Clock

公共静态Clock systemDefaultZone()

获取使用最佳系统时钟返回当前时刻的时钟,并使用默认时区将其转换为日期和时间。

该时钟基于最佳可用系统时钟。它可以使用System.currentTimeMillis(),或者使用更高分辨率的时钟(如果有)。

使用此方法将对默认时区的依赖项硬编码到应用程序中。建议避免这种情况,并尽可能使用特定的时区。当您需要不带日期或时间的当前时刻时,应使用UTC时钟。

返回的实现是不可变的,线程安全的和可序列化的。它等效于system(ZoneId.systemDefault())。

返回值:

在默认区域中使用最佳可用系统时钟的时钟,不为null

也可以看看:

ZoneId.systemDefault()

java.?time.?Clock

公共摘要Instant Instant()

获取时钟的当前时刻。

这将返回一个代表时钟定义的当前时刻的时刻。

返回值:

此时钟的当前时刻,不为null

抛出:

DateTimeException-如果无法获取即时信息,大多数实现都不会抛出该即时信息

感谢您的贡献! 这不仅仅是文档的转储吗? 请解释这如何回答问题。 也最好将引号标记为引号,这样会使答案更易于阅读和理解。

虽然其他一些答案中有正确的信息,但这里是一个简单的摘要。

世界标准时间

根据定义,Instant始终使用UTC。

Instant instant = Instant.now()  // Captures the current moment in UTC. Your default time zone settings are irrelevant.

隐式默认时区

调用LocalTime.now()隐式应用JVM的当前默认时区。

当您键入此代码时:

LocalTime.now()

…JVM在运行时执行以下操作:

LocalTime.now( ZoneId.systemDefault() )

不明显,这就是为什么我建议始终始终将期望/期望的时区显式传递为可选参数的原因。

ZoneId z = ZoneId.systemDefault() ;  // Make explicit the fact that you are intentionally relying on the user’s JVM’s current default time zone.

LocalTime lt = LocalTime.now( z ) ;  // Capture the current moment in the Wall-clock time used by people of a particular region (a time zone).

注意:用户的JVM当前默认时区可以在运行时随时更改。 因此,如果时区很关键,请与用户确认他们的预期时区,并作为可选参数传递。

ZoneId z = ZoneId.of("Africa/Tunis" ) ;  // Or"Europe/Moscow", whatever.

LocalTime lt = LocalTime.now( z ) ;

要了解这些结果,我们必须首先了解Clock是如何工作的。看一下javadoc,我们可以看到以下方法说明:

public abstract Instant instant()

Gets the current instant of the clock.

This returns an instant representing the current instant as defined by the clock.

public abstract ZoneId getZone()

Gets the time-zone being used to create dates and times.

A clock will typically obtain the current instant and then convert that to a date or time using a time-zone. This method returns the time-zone used.

因此instant()方法将获得当前时刻作为java.time.Instant,这是一个始终在UTC中运行的类。这里的重点是:"按时钟定义"。

Clock类允许您创建许多不同的时钟定义-例如始终返回相同内容的固定时钟-最常见的是systemDefaultZone()返回的时钟,它使用系统的当前日期/时间。

由于instant()方法返回java.time.Instant并且此类仅在UTC中起作用,因此结果始终为UTC。

getZone()方法将返回用于创建日期和时间的时区,方法是将Instant(由instant()返回)与getZone()返回的ZoneId组合在一起。

您可以使用所需的任何时区创建时钟,但是systemDefaultZone()仅使用JVM默认时区,在您的情况下为欧洲/莫斯科。

调用LocalTime.now()时,它在内部使用systemDefaultZone()返回的时钟。

然后,它使用来自instant()和getZone()的结果,并将两者组合以获得LocalTime。

用法

根据javadoc:

Use of a Clock is optional. All key date-time classes also have a now() factory method that uses the system clock in the default time zone. The primary purpose of this abstraction is to allow alternate clocks to be plugged in as and when required. Applications use an object to obtain the current time rather than a static method. This can simplify testing.

因此,我不会直接使用时钟。相反,我将根据需要使用每个类中的now方法。

如果我要使用UTC的当前时刻:Instant.now()

仅当前日期:LocalDate.now()

等等...

不带参数的now()方法可以非常方便和方便,但是它有一些缺点。它总是在后台使用JVM默认时区。但是,问题在于,可以通过JVM /系统的配置甚至是在同一VM中运行的任何应用程序随时更改默认时区,而您无法对其进行控制。

要不依赖默认配置,可以使用替代项now(ZoneId)(使用显式时区)或now(Clock),这使您的代码更具可测试性-请参见此处的示例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值