java中的当前时间(以微秒为单位)

java中的当前时间(以微秒为单位),java,timestamp,Java,Timestamp,在Unix系统上,有没有一种方法可以在Java中获得微秒级精度的时间戳?类似于C的gettimeofday函数。不,Java没有这种能力 它确实有System.nanoTime(),但这只是给出了一个与以前已知时间的偏移量。所以,虽然你不能从中得到绝对数,但你可以用它来测量纳秒(或更高)的精度 请注意,JavaDoc说,虽然这提供了纳秒精度,但这并不意味着纳秒精度。因此,取一些适当大的返回值模数。您可以使用: 以纳秒为单位获取时间,但这是一个严格的相对度量。它没有绝对的意义。它仅用于与其他纳米时

在Unix系统上,有没有一种方法可以在Java中获得微秒级精度的时间戳?类似于C的
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)