java中的当前时间(以微秒为单位)
在Unix系统上,有没有一种方法可以在Java中获得微秒级精度的时间戳?类似于C的java中的当前时间(以微秒为单位),java,timestamp,Java,Timestamp,在Unix系统上,有没有一种方法可以在Java中获得微秒级精度的时间戳?类似于C的gettimeofday函数。不,Java没有这种能力 它确实有System.nanoTime(),但这只是给出了一个与以前已知时间的偏移量。所以,虽然你不能从中得到绝对数,但你可以用它来测量纳秒(或更高)的精度 请注意,JavaDoc说,虽然这提供了纳秒精度,但这并不意味着纳秒精度。因此,取一些适当大的返回值模数。您可以使用: 以纳秒为单位获取时间,但这是一个严格的相对度量。它没有绝对的意义。它仅用于与其他纳米时
gettimeofday
函数。不,Java没有这种能力
它确实有System.nanoTime(),但这只是给出了一个与以前已知时间的偏移量。所以,虽然你不能从中得到绝对数,但你可以用它来测量纳秒(或更高)的精度
请注意,JavaDoc说,虽然这提供了纳秒精度,但这并不意味着纳秒精度。因此,取一些适当大的返回值模数。您可以使用:
以纳秒为单位获取时间,但这是一个严格的相对度量。它没有绝对的意义。它仅用于与其他纳米时间进行比较,以测量执行某项操作所需的时间。以下是如何创建无符号长当前时间戳的示例:
UnsignedLong current = new UnsignedLong(new Timestamp(new Date().getTime()).getTime());
如其他海报所示;您的系统时钟可能无法与实际世界时间同步到微秒。尽管如此,微秒精度的时间戳在指示当前墙时间和测量/分析事件持续时间方面还是很有用的 我使用时间戳(如“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) ;
}
}
如果您打算将其用于实时系统,那么java可能不是获取时间戳的最佳选择。但如果你想用if表示唯一键,那么Jason Smith的答案就足够了。但为了以防万一,为了预期两个项目最终得到相同的时间戳(如果这两个项目几乎同时被处理,这是可能的),您可以循环直到最后一个时间戳与当前时间戳不相等
String timestamp = new String();
do {
timestamp = String.valueOf(MicroTimestamp.INSTANCE.get());
item.setTimestamp(timestamp);
} while(lasttimestamp.equals(timestamp));
lasttimestamp = item.getTimestamp();
如果您对Linux感兴趣: 如果您将源代码搜索到“currentTimeMillis()”,您将看到,在Linux上,如果调用此方法,它将返回一微秒的时间。然而,Java随后会截断微秒,并返回毫秒。这在一定程度上是因为Java必须是跨平台的,所以专门为Linux提供方法在当时是一个很大的禁忌(请记住,1.6版本的粗糙软链接支持?!)。这也是因为,虽然在Linux中时钟可以返回微秒,但这并不一定意味着它有利于检查时间。在微秒级,您需要知道NTP并没有重新调整您的时间,并且您的时钟在方法调用期间并没有漂移太多 这意味着,从理论上讲,在Linux上,您可以编写一个与系统包中相同的JNI包装器,但不会截断微秒。我最终使用的“快速且肮脏”解决方案:
TimeUnit.NANOSECONDS.toMicros(System.nanoTime());
更新:
我最初使用System.nanoTime,但后来我发现它应该只用于经过的时间,我最终将代码改为毫秒或在某些地方使用:
TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
但这只会在值的末尾加上零(micros=millis*1000)
在这里留下这个答案作为“警告信号”,以防其他人想到nanoTime:)tl;博士
Java9及更高版本:在捕获当前时刻时达到分辨率。这是小数的9位数字
Instant.now()
2017-12-23T12:34:56.123456789Z
限于
2017-12-23T12:34:56.123456Z
实际上,你只会看到用捕获的微秒。现在
,因为当代传统的计算机硬件时钟在时间上是不精确的
细节
其他答案在Java8中有些过时
java.time
Java 8及更高版本随框架提供。这些新类取代了Java最早版本(如Java.util.date/.Calendar和Java.text.SimpleDataFormat)附带的有缺陷且麻烦的日期时间类。该框架由JSR310定义,受ThreeTen Extra项目的启发和扩展
java.time中的类解析为,比旧的日期时间类和Joda时间使用的更精细。而且比问题中的问题还要好
时钟
实现
虽然java.time类支持以纳秒为单位表示值的数据,但这些类尚未生成以纳秒为单位的值。now()
方法使用与旧日期时间类相同的旧时钟实现。我们在java.time中有了新的Clock
接口,但该接口的实现与旧的毫秒时钟相同
因此,您可以设置ZoneDateTime.now(ZoneId.of(“America/Montreal”))
结果的文本表示格式,以查看小数点秒的九位数字,但只有前三位数字具有如下数字:
2017-12-23T12:34:56.78900000z
Java9中的新时钟
Java 9的OpenJDK和Oracle实现有一个新的默认Clock
实现,具有更精细的粒度,最高可达Java.time类的纳秒级功能
请参阅OpenJDK问题。这一问题已得到成功实施
2017-12-23T12:34:56.123456789Z
在macOS Sierra的MacBook Pro(视网膜,15英寸,2013年末)上,我得到了以微秒为单位的当前时刻(最多六位小数)
2017-12-23T12:34:56.123456Z
硬件时钟
请记住,即使使用新的更精细的时钟
实现,您的结果也可能因计算机而异。Java依赖于底层计算机硬件的时钟来了解当前时刻
- 硬件时钟的分辨率差别很大。例如,如果特定计算机的硬件时钟仅支持粒度,则任何
Instant.now()
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.
long microsenconds = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
long seconds = TimeUnit.MICROSECONDS.toSeconds(microsenconds);
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(); } }
final Timer timer = new TimerImpl(); while (true) { System.out.println(timer.nowNano()); System.out.println(timer.nowMilli()); }
1495065607202174413 1495065607203 1495065607202177574 1495065607203 ... 1495065607372205730 1495065607370 1495065607372208890 1495065607370 ...
val instant = Instant.now(); val currentTimeMicros = instant.getEpochSecond() * 1000_000 + instant.getNano() / 1000;
LocalDateTime.now().truncatedTo(ChronoUnit.MICROS)