AlB*_*lue 142
不,Java没有这种能力.
它确实有System.nanoTime(),但它只是给出了一些先前已知时间的偏移量.因此,虽然您无法从中获取绝对数,但您可以使用它来测量纳秒(或更高)精度.
请注意,JavaDoc表示虽然这提供了纳秒精度,但这并不意味着纳秒精度.因此,取一些适当大的模数的返回值.
Bas*_*que 69
Java 9及更高版本:捕获当前时刻时的分辨率高达纳秒.这是小数部分的9位数.
Instant.now()
Run Code Online (Sandbox Code Playgroud)
2017-12-23T12:34:56.123456789Z
要限制为微秒,请截断.
Instant // Represent a moment in UTC.
.now() // Capture the current moment. Returns a `Instant` object.
.truncatedTo( // Lop off the finer part of this moment.
ChronoUnit.MICROS // Granularity to which we are truncating.
) // Returns another `Instant` object rather than changing the original, per the immutable objects pattern.
Run Code Online (Sandbox Code Playgroud)
2017-12-23T12:34:56.123456Z
从Java 8开始,其他答案有点过时了.
Java 8及更高版本附带了java.time框架.这些新类取代了最早版本的Java附带的有缺陷的麻烦的日期时间类,例如java.util.Date/.Calendar和java.text.SimpleDateFormat.该框架由JSR 310定义,受Joda-Time的启发,由ThreeTen-Extra项目扩展.
java.time中的类解析为纳秒,比旧的日期时间类和Joda-Time使用的毫秒级更精细.并且比问题中提到的微秒更精细.
Clock
履行虽然java.time类支持表示以纳秒为单位的值的数据,但这些类尚未生成以纳秒为单位的值.这些now()
方法使用与旧日期时间类相同的旧时钟实现System.currentTimeMillis()
.我们Clock
在java.time中有新接口,但该接口的实现与旧的毫秒时钟相同.
因此,您可以格式化结果的文本表示,ZonedDateTime.now( ZoneId.of( "America/Montreal" ) )
以查看小数秒的九位数,但只有前三位数字将具有如下数字:
2017-12-23T12:34:56.789000000Z
Java 9的OpenJDK和Oracle实现具有更新的默认Clock
实现,具有更精细的粒度,最高可达java.time类的完整纳秒级功能.
请参阅OpenJDK问题,提高java.time.Clock.systemUTC()的实现精度.该问题已成功实施.
2017-12-23T12:34:56.123456789Z
在使用macOS Sierra的MacBook Pro(Retina,15英寸,2013年末)上,我得到当前时刻,以微秒为单位(最多六位小数).
2017-12-23T12:34:56.123456Z
请记住,即使使用更精细的Clock
实施,您的结果也可能因计算机而异.Java依赖于底层计算机硬件的时钟来了解当前时刻.
cle*_*tus 54
你可以使用System.nanoTime()
:
long start = System.nanoTime();
// do stuff
long end = System.nanoTime();
long microseconds = (end - start) / 1000;
Run Code Online (Sandbox Code Playgroud)
以纳秒为单位获得时间,但这是一个严格的相对衡量标准.它没有绝对的意义.它仅用于与其他纳米时间进行比较,以衡量某些事情需要多长时间.
Jas*_*ith 14
正如其他海报已经表明的那样; 您的系统时钟可能不会同步到微秒到实际世界时间.尽管如此,微秒精度时间戳可用作指示当前壁时间和测量/分析事物持续时间的混合.
我使用诸如"2012-10-21 19:13:45.267128"之类的时间戳标记写入日志文件的所有事件/消息.这些都在它发生时("墙"时间)传达,并且还可以用于测量日志文件中该事件与下一事件之间的持续时间(以微秒为单位的相对差异).
要实现这一点,您需要将System.currentTimeMillis()与System.nanoTime()链接起来,并从此刻开始专门使用System.nanoTime().示例代码:
/**
* Class to generate timestamps with microsecond precision
* For example: MicroTimestamp.INSTANCE.get() = "2012-10-21 19:13:45.267128"
*/
public enum MicroTimestamp
{ INSTANCE ;
private long startDate ;
private long startNanoseconds ;
private SimpleDateFormat dateFormat ;
private MicroTimestamp()
{ this.startDate = System.currentTimeMillis() ;
this.startNanoseconds = System.nanoTime() ;
this.dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS") ;
}
public String get()
{ long microSeconds = (System.nanoTime() - this.startNanoseconds) / 1000 ;
long date = this.startDate + (microSeconds/1000) ;
return this.dateFormat.format(date) + String.format("%03d", microSeconds % 1000) ;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以创建一个组件来确定 System.nanoTime() 和 System.currentTimeMillis() 之间的偏移量,并有效地获得自纪元以来的纳秒。
public class TimerImpl implements Timer {
private final long offset;
private static long calculateOffset() {
final long nano = System.nanoTime();
final long nanoFromMilli = System.currentTimeMillis() * 1_000_000;
return nanoFromMilli - nano;
}
public TimerImpl() {
final int count = 500;
BigDecimal offsetSum = BigDecimal.ZERO;
for (int i = 0; i < count; i++) {
offsetSum = offsetSum.add(BigDecimal.valueOf(calculateOffset()));
}
offset = (offsetSum.divide(BigDecimal.valueOf(count))).longValue();
}
public long nowNano() {
return offset + System.nanoTime();
}
public long nowMicro() {
return (offset + System.nanoTime()) / 1000;
}
public long nowMilli() {
return System.currentTimeMillis();
}
}
Run Code Online (Sandbox Code Playgroud)
以下测试在我的机器上产生了相当好的结果。
final Timer timer = new TimerImpl();
while (true) {
System.out.println(timer.nowNano());
System.out.println(timer.nowMilli());
}
Run Code Online (Sandbox Code Playgroud)
差异似乎在 +-3ms 的范围内振荡。我想可以稍微调整偏移计算。
1495065607202174413
1495065607203
1495065607202177574
1495065607203
...
1495065607372205730
1495065607370
1495065607372208890
1495065607370
...
Run Code Online (Sandbox Code Playgroud)