gpt4 book ai didi

java - (Oracle) Java JVM 如何知道闰秒正在发生?

转载 作者:IT老高 更新时间:2023-10-28 20:55:55 25 4
gpt4 key购买 nike

一个 leap second will occur 2015 年 6 月 30 日。不同的操作系统似乎以不同的方式处理这种情况。在我的特殊情况下,我们正在运行一个 Red Hat 6.4 系统,该系统带有高度依赖时间的定制 Java (JDK 1.7) 软件。根据一些 recent Red Hat released information我发现,我们系统的 NTP 守护进程会通过重复 23:59:59 两次来确保操作系统自动处理闰秒。

我的问题是:如果我有一个长时间运行的 JDK 1.7 进程,它如何知道闰秒正在发生?我的意思是,Java 最终如何知道 IERS人们已经决定插入闰秒? Date文档似乎表明知道闰秒,但似乎无济于事。我可以假设 JDK,当构造适当的 Date 对象或调用 Calendar.getInstance() 时,它是对底层操作系统的日期时间处理的传递获得适当的“实时”时间值? (在我的情况下,听起来它会在 23:59:59 重复第二次,因为这就是操作系统将处理它的方式)。

最佳答案

The Answerassylias是正确的。这个答案添加了一些由对该答案的评论引发的想法。该评论提到在计划闰秒时计算午夜耗时。

这个答案也确实解决了原始问题,指出对于实际使用,闰秒的问题没有实际意义,被日期时间框架忽略。

忽略闰秒

据我所知,所有常见的 Java 日期时间框架都会忽略闰秒。其中包括:

  • java.time
  • Joda-Time
  • java.util.Date/.Calendar(现在已被 java.time 和 Joda-Time 过时)

文档

这里是每个框架文档的摘录,表明它们实际上忽略了闰秒。粗体字的重点是我的。

Instant 的 java.time 文档类:

… Given the complexity of accurate timekeeping described above, this Java API defines its own time-scale, the Java Time-Scale.

The Java Time-Scale divides each calendar day into exactly 86400 subdivisions, known as seconds. These seconds may differ from the SI second. It closely matches the de facto international civil time scale, the definition of which changes from time to time.

The Java Time-Scale has slightly different definitions for different segments of the time-line, each based on the consensus international time scale that is used as the basis for civil time. Whenever the internationally-agreed time scale is modified or replaced, a new segment of the Java Time-Scale must be defined for it. Each segment must meet these requirements:

  • the Java Time-Scale shall closely match the underlying international civil time scale;
  • the Java Time-Scale shall exactly match the international civil time scale at noon each day;
  • the Java Time-Scale shall have a precisely-defined relationship to the international civil time scale.

There are currently, as of 2013, two segments in the Java time-scale.

For the segment from 1972-11-03 (exact boundary discussed below) until further notice, the consensus international time scale is UTC (with leap seconds). In this segment, the Java Time-Scale is identical to UTC-SLS. This is identical to UTC on days that do not have a leap second. On days that do have a leap second, the leap second is spread equally over the last 1000 seconds of the day, maintaining the appearance of exactly 86400 seconds per day.

For the segment prior to 1972-11-03, extending back arbitrarily far, the consensus international time scale is defined to be UT1, applied proleptically, which is equivalent to the (mean) solar time on the prime meridian (Greenwich). In this segment, the Java Time-Scale is identical to the consensus international time scale. The exact boundary between the two segments is the instant where UT1 = UTC between 1972-11-03T00:00 and 1972-11-04T12:00.

Implementations of the Java time-scale using the JSR-310 API are not required to provide any clock that is sub-second accurate, or that progresses monotonically or smoothly. Implementations are therefore not required to actually perform the UTC-SLS slew or to otherwise be aware of leap seconds. JSR-310 does, however, require that implementations must document the approach they use when defining a clock representing the current instant. See Clock for details on the available clocks.

The Java time-scale is used for all date-time classes. This includes Instant, LocalDate, LocalTime, OffsetDateTime, ZonedDateTime and Duration.

Joda-Time FAQ :

Joda-Time does not support leap seconds. Leap seconds can be supported by writing a new, specialized chronology, or by making a few enhancements to the existing ZonedChronology class. In either case, future versions of Joda-Time will not enable leap seconds by default. Most applications have no need for it, and it might have additional performance costs.

java.util.Date class doc :

A second is represented by an integer from 0 to 61; the values 60 and 61 occur only for leap seconds and even then only in Java implementations that actually track leap seconds correctly.

据我所知,OpenJDK 和 Oracle 提供的实现跟踪闰秒。如果您找到它,请发布此类文档。

计算耗时时没有闰秒

因此,这些框架在计算耗时时不会报告额外的闰秒。

这里是一些示例代码,用于计算从 2015 年 6 月 30 日到 7 月 1 日午夜前一分钟到之后一分钟所耗时,此时 Leap Second已安排。此代码在 java version "1.8.0_45" 中测试 Joda-Time 2.8.1 和 java-time。我忽略了 java.util.Date/.Calendar,因为我尽可能避免使用这些类;如果需要,请随时在此处为这种情况添加代码。

第一个 Joda-Time .

// Joda-Time 2.8.1
DateTime startJoda = new DateTime( 2015, 06, 30, 23, 59, 00, DateTimeZone.UTC );
DateTime stopJoda = new DateTime( 2015, 07, 01, 00, 01, 00, DateTimeZone.UTC );
long elapsedMillisJoda = ( stopJoda.getMillis( ) - startJoda.getMillis( ) );

System.out.println( "startJoda: " + startJoda + " stopJoda: " + stopJoda + " = elapsedMillisJoda: " + elapsedMillisJoda );

…和java.time

// java.time
ZonedDateTime startZdt = ZonedDateTime.of( 2015, 06, 30, 23, 59, 00, 00, ZoneOffset.UTC );
ZonedDateTime stopZdt = ZonedDateTime.of( 2015, 07, 01, 00, 01, 00, 00, ZoneOffset.UTC );
long elapsedMillisZdt = startZdt.until( stopZdt, ChronoUnit.MILLIS );

System.out.println( "startZdt: " + startZdt + " stopZdt: " + stopZdt + " = elapsedMillisZdt: " + elapsedMillisZdt );

运行时,我们会看到偶数的结果,正好是 2 分钟、120 秒或 120,000 毫秒。

startJoda: 2015-06-30T23:59:00.000Z stopJoda: 2015-07-01T00:01:00.000Z = elapsedMillisJoda: 120000
startZdt: 2015-06-30T23:59Z stopZdt: 2015-07-01T00:01Z = elapsedMillisZdt: 120000

关于java.time

java.time框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy日期时间类,例如 java.util.Date , Calendar , & SimpleDateFormat .

Joda-Time项目,现在在 maintenance mode , 建议迁移到 java.time类。

要了解更多信息,请参阅 Oracle Tutorial .并在 Stack Overflow 上搜索许多示例和解释。规范为 JSR 310 .

使用 JDBC driver符合 JDBC 4.2或者以后,您可以直接与您的数据库交换 java.time 对象。不需要字符串也不需要 java.sql.* 类。

从哪里获得 java.time 类?

ThreeTen-Extra项目通过附加类扩展了 java.time。该项目是 future 可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如 Interval , YearWeek , YearQuarter , 和 more .

关于java - (Oracle) Java JVM 如何知道闰秒正在发生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30984599/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com