唯一的问题在于时间分辨率。通常情况下,Java通过java.util.Date
或System.currentTimeMillis()
支持毫秒精度。如果您需要更高的精度,则System.nanoTime()
可能会起到作用。
但这带来了另一个问题-nanoTime()
与任何日历无关,它只是一个具有纳秒精度的不断增长的计数器。我能想到的唯一解决方法是:
确定午夜时刻System.nanoTime()
的值,称之为S
。这可能有问题,但你不必等到午夜,一些简单的数学就足够了。
计算以下内容:
(System.nanoTime() - S) / 15000
如果该值为0
,则我们处于相同的15微秒范围内
你确定JVM和你的程序真的能够利用这么短的时间吗?
Java 8及更高版本使此任务变得非常容易: 将Clock
的替代实现作为可选参数传递给java.time类。
Instant.now( // Capture the current moment.
Clock.tick( // Access an alternate implementation of `Clock`.
Clock.systemDefaultZone() , // Start with the regular default implementation.
Duration.of( 10 , ChronoUnit.MICROS ) // Override to increment the “ticking” of the clock by this amount of time. Here we specify 10 microseconds, as 15 microseconds does not divide evenly into a whole second.
)
) // Returns an `Instant` object, the class replacing `java.util.Date`.
跟踪日期时间的现代方法使用java.time类。
这些类可以带有一个可选参数Clock
。这在开发和测试期间需要更改或人工时钟时非常方便。
您可以实现自己的Clock
。但是,Clock
类本身捆绑了几个替代实现之一是Clock.tick(clock, duration)
,它通过指定的Duration
增加时间。
获取从指定时钟截断到最近出现指定持续时间的瞬间的时钟。
问题在于小数秒数量必须均匀分配,正如文档所述:
如果时间间隔小于一毫秒,那么整个持续时间必须能够被一秒整除而不留余数。所有正常的滴答间隔都将符合这些标准,包括任何小时、分钟、秒和毫秒的倍数,以及合理的纳秒间隔,例如20ns、250,000ns和500,000ns。Instant.now( clock ) // Override default `Clock`.
所以这里不能使用15微秒,但是10微秒可以。如果您考虑一下,这个规则是否也适用于问题,因为从零开始的15微秒块不会形成一个整数秒?
Duration d = Duration.of( 10 , ChronoUnit.MICROS ) ; // Define a span of time by which we want to increment the reporting of the current moment.
Clock clock = Clock.tick( Clock.systemDefaultZone() , d ); // Define a clock that increments by this span of time.
for ( int i = 1 ; i < 100 ; i++ ) {
System.out.println( Instant.now( clock ) ); // Override default `Clock` implementation with our special “chunky” incrementing clock.
// Sleep a moment.
try {
Thread.sleep( 3 ); // Sleep arbitrary amount of time.
} catch ( InterruptedException e ) {
e.printStackTrace();
}
}
2018-04-04T21:55:46.537750Z
2018-04-04T21:55:46.550280Z
2018-04-04T21:55:46.553570Z
2018-04-04T21:55:46.556980Z
2018-04-04T21:55:46.560850Z
…
java.time框架内置于Java 8及以上版本。这些类替代了老旧且麻烦的传统日期时间类,如{{link3:java.util.Date
}}、{{link4:Calendar
}}和{{link5:SimpleDateFormat
}}。
Joda-Time 项目现在处于维护模式,建议迁移到 java.time 类。
想要了解更多,请参阅 Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是 JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序。无需字符串,也不需要 java.sql.*
类。
如何获取 java.time 类?
ThreeTen-Extra 项目通过增加类来扩展 java.time。该项目是 java.time 可能未来加入的候选项。您可能会在此找到一些有用的类,如 Interval
、YearWeek
、YearQuarter
,以及 更多。
您可能想查看this问题,以获取有关获取微秒时间的信息。Java不太支持微秒日期计时。
Java支持毫秒级日期,并且在某些系统上,您可以通过System.nanoTime()
获得纳秒级系统时间。如果您的系统支持纳秒分辨率,则编写一个函数将您的纳秒数转换并将其舍入到15微秒块将非常容易。