java中的当前时间(以微秒为单位)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1712205/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Current time in microseconds in java
提问by Seth
On a Unix system, is there a way to get a timestamp with microsecond level accuracy in Java? Something like C's gettimeofday
function.
在 Unix 系统上,有没有办法在 Java 中获得微秒级精度的时间戳?有点像 C 的gettimeofday
函数。
采纳答案by AlBlue
No, Java doesn't have that ability.
不,Java 没有这种能力。
It does have System.nanoTime(), but that just gives an offset from some previously known time. So whilst you can't take the absolute number from this, you can use it to measure nanosecond (or higher) precision.
它确实有 System.nanoTime(),但这只是给出了一些先前已知时间的偏移量。因此,虽然您不能从中获取绝对数字,但您可以使用它来测量纳秒(或更高)精度。
Note that the JavaDoc says that whilst this provides nanosecond precision, that doesn't mean nanosecond accuracy. So take some suitably large modulus of the return value.
请注意,JavaDoc 说虽然这提供了纳秒精度,但这并不意味着纳秒精度。所以取一些适当大的返回值模数。
回答by cletus
You can use System.nanoTime()
:
您可以使用System.nanoTime()
:
long start = System.nanoTime();
// do stuff
long end = System.nanoTime();
long microseconds = (end - start) / 1000;
to get time in nanoseconds but it is a strictly relative measure. It has no absolute meaning. It is only useful for comparing to other nano times to measure how long something took to do.
以纳秒为单位获得时间,但这是一个严格的相对度量。它没有绝对的意义。它仅用于与其他纳米时间进行比较以测量某事花费的时间。
回答by cletus
Here is an example of how to create an UnsignedLong current Timestamp:
以下是如何创建 UnsignedLong 当前时间戳的示例:
UnsignedLong current = new UnsignedLong(new Timestamp(new Date().getTime()).getTime());
回答by Jason Smith
As other posters already indicated; your system clock is probably not synchronized up to microseconds to actual world time. Nonetheless are microsecond precision timestamps useful as a hybrid for both indicating current wall time, and measuring/profiling the duration of things.
正如其他海报已经指出的那样;您的系统时钟可能不会与实际世界时间同步至微秒。尽管如此,微秒精度时间戳作为一种混合体还是很有用的,既可以指示当前的墙时间,又可以测量/分析事物的持续时间。
I label all events/messages written to a log files using timestamps like "2012-10-21 19:13:45.267128". These convey both whenit happened ("wall" time), and can also be used to measure the durationbetween this and the next event in the log file (relative difference in microseconds).
我使用诸如“2012-10-21 19:13:45.267128”之类的时间戳标记写入日志文件的所有事件/消息。这些既传送时它发生(“壁”的时间),并且还可以用于测量持续时间这一点,并在日志文件中的下一个事件(微秒相对差异)之间。
To achieve this, you need to link System.currentTimeMillis() with System.nanoTime() and work exclusively with System.nanoTime() from that moment forward. Example code:
要实现这一点,您需要将 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) ;
}
}
回答by wingedcrown
If you intend to use it for realtime system, perhaps java isnt the best choice to get the timestamp. But if youre going to use if for unique key, then Jason Smith's answer will do enough. But just in case, to anticipate 2 item end up getting the same timestamp (its possible if those 2 were processed almost simultaneously), you can loop until the last timestamp not equals with the current timestamp.
如果您打算将它用于实时系统,也许 java 不是获取时间戳的最佳选择。但是,如果您要使用 if 作为唯一键,那么 Jason Smith 的答案就足够了。但以防万一,为了预期 2 个项目最终获得相同的时间戳(如果这 2 个几乎同时处理,则可能),您可以循环直到最后一个时间戳与当前时间戳不相等。
String timestamp = new String();
do {
timestamp = String.valueOf(MicroTimestamp.INSTANCE.get());
item.setTimestamp(timestamp);
} while(lasttimestamp.equals(timestamp));
lasttimestamp = item.getTimestamp();
回答by zamhassam
If you're interested in Linux: If you fish out the source code to "currentTimeMillis()", you'll see that, on Linux, if you call this method, it gets a microsecond time back. However Java then truncates the microseconds and hands you back milliseconds. This is partly because Java has to be cross platform so providing methods specifically for Linux was a big no-no back in the day (remember that cruddy soft link support from 1.6 backwards?!). It's also because, whilst you clock can give you back microseconds in Linux, that doesn't necessarily mean it'll be good for checking the time. At microsecond levels, you need to know that NTP is not realigning your time and that your clock has not drifted too much during method calls.
如果您对 Linux 感兴趣:如果您找到“currentTimeMillis()”的源代码,您会看到,在 Linux 上,如果您调用此方法,它会返回微秒时间。然而,Java 会截断微秒并返回毫秒。这在一定程度上是因为 Java 必须是跨平台的,因此提供专门用于 Linux 的方法在当时是一个很大的禁忌(还记得从 1.6 向后的粗糙软链接支持吗?!)。这也是因为,虽然您的时钟可以在 Linux 中返回微秒,但这并不一定意味着它可以很好地检查时间。在微秒级别,您需要知道 NTP 不会重新调整您的时间,并且您的时钟在方法调用期间没有漂移太多。
This means, in theory, on Linux, you could write a JNI wrapper that is the same as the one in the System package, but not truncate the microseconds.
这意味着,理论上,在 Linux 上,您可以编写与 System 包中相同的 JNI 包装器,但不截断微秒。
回答by keisar
a "quick and dirty" solution that I eventually went with:
我最终采用的“快速而肮脏”的解决方案:
TimeUnit.NANOSECONDS.toMicros(System.nanoTime());
UPDATE:
更新:
I originally went with System.nanoTime but then I found out it should only be used for elapsed time, I eventually changed my code to work with milliseconds or at some places use:
我最初使用 System.nanoTime 但后来我发现它应该只用于经过的时间,我最终更改了我的代码以使用毫秒或在某些地方使用:
TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
but this will just add zeros at the end of the value (micros = millis * 1000)
但这只会在值的末尾添加零(微 = 毫秒 * 1000)
Left this answer here as a "warning sign" in case someone else thinks of nanoTime :)
将此答案留在这里作为“警告标志”,以防其他人想到 nanoTime :)
回答by Basil Bourque
tl;dr
tl;博士
Java 9 and later: Up to nanosecondsresolution when capturing the current moment. That's 9 digits of decimal fraction.
Java 9 及更高版本:捕获当前时刻时分辨率高达纳秒。那是 9 位小数。
Instant.now()
2017-12-23T12:34:56.123456789Z
2017-12-23T12:34:56.123456789Z
To limit to microseconds, truncate.
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.
2017-12-23T12:34:56.123456Z
2017-12-23T12:34:56.123456Z
In practice, you will see only microseconds captured with .now
as contemporary conventional computer hardware clocks are not accurate in nanoseconds.
在实践中,您只会看到捕获的微秒,.now
因为当代传统计算机硬件时钟在纳秒内并不准确。
Details
细节
The other Answers are somewhat outdated as of Java 8.
从 Java 8 开始,其他答案有些过时。
java.time
时间
Java 8 and later comes with the java.timeframework. These new classes supplant the flawed troublesome date-time classes shipped with the earliest versions of Java such as java.util.Date/.Calendar and java.text.SimpleDateFormat. The framework is defined by JSR 310, inspired by Joda-Time, extended by the ThreeTen-Extra project.
Java 8 及更高版本带有java.time框架。这些新类取代了 Java 最早版本附带的有缺陷的麻烦日期时间类,例如 java.util.Date/.Calendar 和 java.text.SimpleDateFormat。该框架由 JSR 310 定义,受Joda-Time启发,由 ThreeTen-Extra 项目扩展。
The classes in java.time resolve to nanoseconds, much finer than the millisecondsused by both the old date-time classes and by Joda-Time. And finer than the microsecondsasked in the Question.
在java.time决心的类纳秒,更精细的比毫秒双方旧日期,时间类和乔达时使用。并且比问题中提出的微秒更精细。
Clock
Implementation
Clock
执行
While the java.time classes support data representing values in nanoseconds, the classes do not yet generatevalues in nanoseconds. The now()
methods use the same old clock implementation as the old date-time classes, System.currentTimeMillis()
. We have the new Clock
interface in java.time but the implementation for that interface is the same old milliseconds clock.
虽然 java.time 类支持以纳秒为单位表示值的数据,但这些类尚未生成以纳秒为单位的值。这些now()
方法使用与旧日期时间类相同的旧时钟实现System.currentTimeMillis()
。我们Clock
在 java.time 中有新接口,但该接口的实现是相同的旧毫秒时钟。
So you could format the textual representation of the result of ZonedDateTime.now( ZoneId.of( "America/Montreal" ) )
to see nine digits of a fractional second but only the first three digits will have numbers like this:
因此,您可以格式化结果的文本表示ZonedDateTime.now( ZoneId.of( "America/Montreal" ) )
以查看小数秒的九位数字,但只有前三位数字会具有如下数字:
2017-12-23T12:34:56.789000000Z
2017-12-23T12:34:56.789000000Z
New Clock In Java 9
Java 9 中的新时钟
The OpenJDK and Oracle implementations of Java 9 have a new default Clock
implementation with finer granularity, up to the full nanosecond capability of the java.time classes.
Java 9 的 OpenJDK 和 Oracle 实现有一个新的默认Clock
实现,粒度更细,达到 java.time 类的完整纳秒功能。
See the OpenJDK issue, Increase the precision of the implementation of java.time.Clock.systemUTC(). That issue has been successfully implemented.
请参阅 OpenJDK 问题,提高 java.time.Clock.systemUTC() 的实现精度。该问题已成功实施。
2017-12-23T12:34:56.123456789Z
2017-12-23T12:34:56.123456789Z
On a MacBook Pro (Retina, 15-inch, Late 2013) with macOS Sierra, I get the current moment in microseconds (up to six digits of decimal fraction).
在装有 macOS Sierra 的 MacBook Pro(Retina,15 英寸,2013 年末)上,我获得了以微秒为单位的当前时刻(最多六位小数)。
2017-12-23T12:34:56.123456Z
2017-12-23T12:34:56.123456Z
Hardware Clock
硬件时钟
Remember that even with a new finer Clock
implementation, your results may vary by computer. Java depends on the underlying computer hardware's clock to know the current moment.
请记住,即使使用新的更精细的Clock
实现,您的结果也可能因计算机而异。Java 依赖于底层计算机硬件的时钟来了解当前时刻。
- The resolutionof the hardware clocks vary widely. For example, if a particular computer's hardware clock supports only microsecondsgranularity, any generated date-time values will have only six digits of fractional second with the last three digits being zeros.
- The accuracyof the hardware clocks vary widely. Just because a clock generates a value with several digits of decimal fraction of a second, those digits may be inaccurate, just approximations, adrift from actual time as might be read from an atomic clock. In other words, just because you see a bunch of digits to the right of the decimal mark does not mean you can trust the elapsed time between such readings to be true to that minute degree.
回答by tanghao
Java support microseconds through TimeUnit
enum.
Java 通过TimeUnit
枚举支持微秒。
Here is the java doc: Enum TimeUnit
这是 Java 文档: Enum TimeUnit
You can get microseconds in java by this way:
你可以通过这种方式在java中获得微秒:
long microsenconds = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
You also can convert microseconds back to another time units, for example:
您还可以将微秒转换回另一个时间单位,例如:
long seconds = TimeUnit.MICROSECONDS.toSeconds(microsenconds);
回答by kangcz
You could maybe create a component that determines the offset between System.nanoTime() and System.currentTimeMillis() and effectively get nanoseconds since epoch.
您可以创建一个组件来确定 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();
}
}
Following test produces fairly good results on my machine.
以下测试在我的机器上产生了相当好的结果。
final Timer timer = new TimerImpl();
while (true) {
System.out.println(timer.nowNano());
System.out.println(timer.nowMilli());
}
The difference seems to oscillate in range of +-3ms. I guess one could tweak the offset calculation a bit more.
差异似乎在 +-3ms 的范围内振荡。我想可以稍微调整偏移计算。
1495065607202174413
1495065607203
1495065607202177574
1495065607203
...
1495065607372205730
1495065607370
1495065607372208890
1495065607370
...