I am trying to get microseconds from a Date, but I can't.
Date date = new Date()
No, Date only stores values to millisecond accuracy. If you want microsecond accuracy, you might want to look at JSR-310, or java.sql.Timestamp as a bit of a hack - but don't expect any of the built-in classes such as Calendar and DateFormat to handle anything beyond milliseconds.
If you're trying to perform timing (e.g. for benchmarking) you should use System.nanoTime, but that should only be used for stopwatch-like use cases - it doesn't give you the "current wallclock time" in a meaningful way.
What I do is find the difference between the currentTimeMillis and the nanoTime() at regular intervals (as this drifts quite a bit) and use nanoTime() + OFFSET for a currentTimeNS. (More specificity I use the RDTSC machine code instruction, which comes with even more quibbles ;)
However, its is less accurate than currenTimeMillis() over time which itself can drifts by many milli-seconds in an hour.
It only really useful if you understand its limitations.
To measure time in microseconds you need to use the System.nanoTime() function which will return a time in microseconds based on the most accurate clock available to your system.
To the user this acts in pretty much the same way as System.currentTimeMilis() does for milliseconds, you simply define your start and end times and then negate the difference to find out how long an action took. For example:
long startTime = System.nanoTime();
//Do some kind of processing;
//loop, IO, whatever you want to measure
long endTime = System.nanoTime();
long elapsedTime = endTime - startTime;
The last bit can be shorted, I've left it verbose for simplicity:
long elapsedTime = System.nanoTime() - startTime;
This should not be used to measure real time as it has very little meaning or guarantee that it is even comparable to it. All of the above information is available from the Java API documentation for System.
Related
In Java, we can have many different ways to get the current timestamp, but which one is recommended:
Instant.now().toEpochMilli() or System.currentTimeMillis()
Both are fine. And neither is recommended except for a minority of purposes.
What do you need milliseconds since the epoch for?
In Java, we can have many different ways to get the current timestamp,
For current timestamp just use Instant.now(). No need to convert to milliseconds.
Many methods from the first years of Java, also many in the standard library, took a long number of milliseconds since the epoch as argument. However, today I would consider that old-fashioned. See if you can find — or create — or more modern method that takes for instance an Instant as argument instead. Go object-oriented and don’t use a primitive long. It will make your code clearer and more self-explanatory.
As Eliott Frisch said in a comment, if this is for measuring elapsed time, you may prefer the higher resolution of System.nanoTime().
If you do need milliseconds since the epoch
Assuming that you have good reasons for wanting a count of milliseconds since the epoch, …
which one is recommended: Instant.now().toEpochMilli() or
System.currentTimeMillis()[?]
Opinions differ. Some will say that you should use java.time, the modern date and time API, for all of your date and time work. This would imply Instant here. Unsg java.time is generally a good habit since the date and time classes from Java 1.0 and 1.1 (Date, Calendar, TimeZone, DateFormat, SimpleDateFormat and others) are poorly designed and now long outdated, certainly not any that we should use anymore. On the other hand I am not aware of any design problem with System.curremtTimeMillis() in particular (except what I mentioned above about using a long count of milliseconds at all, which obviously is intrinsic to both Instant.now().toEpochMilli() and System.currentTimeMillis()).
If there is a slight performance difference between the two, I have a hard time imagining the situation where this will matter.
Take the option that you find more readable and less surprising in your context.
Similar questions
JSR 310 :: System.currentTimeMillis() vs Instant.toEpochMilli() :: TimeZone
Java current time different values in api
As per my understanding Instant.now().toEpochMilli() is better as Java-8 onward usage of Instant has been recommended.
Also, it works based on timeline and instant represents a specific moment on that timeline.
In case of java.lang.System.currentTimeMillis() method it returns the current time in milliseconds. The granularity of the value depends on the underlying operating system and may be larger.
Hence, to be consistent altogether use Instant.
I want to add that System.nanoTime() is less about precision but more about accuracy.
System.currentTimeMillis() is based on the system clock, which is, most of the time, based on a quartz clock inside a computer. It is not accurate and it drifts. (VM is even worse since you don't have a physical clock and have to sync with the host) When your computer syncs this quartz clock with a global clock, you might even observe your clock jumps backward/forward because your local clock is too fast or slow.
On the other hand, System.nanoTime() is based on a monotonic clock. This clock has nothing to do with the actual time we humans speak. It only moves forward at a constant pace. It does not drift like the quartz clock and there is no sync required. This is why it is perfect for measuring elapses.
For what it's worth, I've done a quick non-ideal performance test comparing the two methods.
On my system (Ubuntu 20.04, OpenJDK 17.0.4), running System.currentTimeMillis ten million times takes cca 230ms while running Instant.now().toEpochMilli() ten million times takes cca 370ms.
import java.time.Instant;
public class A {
public static void main(String[] args) {
long a = 0;
long start = System.currentTimeMillis();
for (int i = 0; i < 10_000_000; i++) {
//a += Instant.now().toEpochMilli();
a += System.currentTimeMillis();
}
System.out.println(a);
System.out.println(System.currentTimeMillis() - start);
}
}
I created a presentation rendering framework using java. In need to calculate how much time taken by the user for the each frame in the presentation. So is there is any api or framework in java which looks like a stopwatch.
For measurement you could use:
System.nanoTime();
Returns the current value of the most precise available system timer, in nanoseconds.
This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time. The value returned represents nanoseconds since some fixed but arbitrary time.
for example from oracle documentation:
long startTime = System.nanoTime();
// ... the code being measured ...
long estimatedTime = System.nanoTime() - startTime;
Use System.nanoTime() which exists precisely for this purpose. If you want extra goodies like easy manipulation of elapsed time, support for laps, then you can have a look at the com.google.common.base.StopWatch in the Guava library.
Example:
Stopwatch stopwatch = Stopwatch.createStarted();
doSomething();
stopwatch.stop(); // optional
long millis = stopwatch.elapsed(MILLISECONDS);
log.info("time: " + stopwatch); // formatted string like "12.3 ms"
Guava also includes other goodies like collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, and so forth.
http://docs.oracle.com/javase/6/docs/api/java/sql/Timestamp.html
The only non-deprecated ctor takes millis. Is there no way to ask for 'now' including nanos.
getNanos()/setNanos(int) on Timestamp exists to support databases that return the timestamp data type with nanosecond precision.
Java does not have a means to get the current time with nanosecond precision. System.nanoTime() returns elapsed nanoseconds from some unknown epoch chosen by the JVM. It is useful for measuring elapsed time between two calls of System.nanoTime(). Even then while System.nanoTime() can measure elapsed time between calls to nanosecond precision it is not necessarily accurate to nanosecond precision as mentioned in the javadocs.
As has been noted in comments on other answers, System.nanoTime() doesn't really return any meaningful values regarding time in nanoseconds.
I would like to point to this discussion from SO which points out why we can't get better accuracy on our time measurements. It would appear to imply that it is not really possible to do as you ask, and that it would be against some Java design goals to try and include this ability, due to portability and platform constraints.
So, in answer to your question, I would say no, but only based upon the answers of people with more rep than me.
On a Unix system, is there a way to get a timestamp with microsecond level accuracy in Java? Something like C's gettimeofday function.
No, Java doesn't have that ability.
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.
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.
tl;dr
Java 9 and later: Up to nanoseconds resolution when capturing the current moment. That’s 9 digits of decimal fraction.
Instant.now()
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
In practice, you will see only microseconds captured with .now as contemporary conventional computer hardware clocks are not accurate in nanoseconds.
Details
The other Answers are somewhat outdated as of Java 8.
java.time
Java 8 and later comes with the java.time framework. 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.
The classes in java.time resolve to nanoseconds, much finer than the milliseconds used by both the old date-time classes and by Joda-Time. And finer than the microseconds asked in the Question.
Clock Implementation
While the java.time classes support data representing values in nanoseconds, the classes do not yet generate values 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.
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:
2017-12-23T12:34:56.789000000Z
New Clock In 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.
See the OpenJDK issue, Increase the precision of the implementation of java.time.Clock.systemUTC(). That issue has been successfully implemented.
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).
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.
The resolution of the hardware clocks vary widely. For example, if a particular computer’s hardware clock supports only microseconds granularity, any generated date-time values will have only six digits of fractional second with the last three digits being zeros.
The accuracy of 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.
You can use 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.
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 when it happened ("wall" time), and can also be used to measure the duration between this and the next event in the log file (relative difference in microseconds).
To achieve this, you need to link System.currentTimeMillis() with System.nanoTime() and work exclusively with System.nanoTime() from that moment forward. Example code:
/**
* 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) ;
}
}
You could maybe create a component that determines the offset between System.nanoTime() and System.currentTimeMillis() and effectively get nanoseconds since epoch.
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.
1495065607202174413
1495065607203
1495065607202177574
1495065607203
...
1495065607372205730
1495065607370
1495065607372208890
1495065607370
...
Use Instant to compute microseconds since Epoch:
val instant = Instant.now();
val currentTimeMicros = instant.getEpochSecond() * 1000_000 + instant.getNano() / 1000;
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:
TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
but this will just add zeros at the end of the value (micros = millis * 1000)
Left this answer here as a "warning sign" in case someone else thinks of nanoTime :)
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.
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.
Java support microseconds through TimeUnit enum.
Here is the java doc:
Enum TimeUnit
You can get microseconds in java by this way:
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);
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.
String timestamp = new String();
do {
timestamp = String.valueOf(MicroTimestamp.INSTANCE.get());
item.setTimestamp(timestamp);
} while(lasttimestamp.equals(timestamp));
lasttimestamp = item.getTimestamp();
LocalDateTime.now().truncatedTo(ChronoUnit.MICROS)
Here is an example of how to create an UnsignedLong current Timestamp:
UnsignedLong current = new UnsignedLong(new Timestamp(new Date().getTime()).getTime());
I'm timing some things, which I can't just put in a long loop. And I need to time them to see how long they take to complete, but it seems like the timer has a 15-16 ms accuracy in java? How can i get around this?
Have you tried using System.nanoTime()?
From the Javadoc:
Returns the current value of the most precise available system timer, in nanoseconds.
This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time. The value returned represents nanoseconds since some fixed but arbitrary time (perhaps in the future, so values may be negative). This method provides nanosecond precision, but not necessarily nanosecond accuracy. No guarantees are made about how frequently values change. Differences in successive calls that span greater than approximately 292 years (263 nanoseconds) will not accurately compute elapsed time due to numerical overflow.
For example, to measure how long some code takes to execute:
long startTime = System.nanoTime();
// ... the code being measured ...
long estimatedTime = System.nanoTime() - startTime;
Clocks and Timers - General Overview
Java Programming API's for Clocks and Timers The absolute
"time-of-day" clock is represented by
the System.currentTimeMillis() method,
that returns a millisecond
representation of wall-clock time in
milliseconds since the epoch. As such
it uses the operating system's "time
of day" clock. The update resolution
of this clock is often the same as the
timer interrupt (eg. 10ms), but on
some systems is fixed, independent of
the interrupt rate.
The relative-time clock is represented
by the System.nanoTime() method that
returns a "free-running" time in
nanoseconds. This time is useful only
for comparison with other nanoTime
values. The nanoTime method uses the
highest resolution clock available on
the platform, and while its return
value is in nanoseconds, the update
resolution is typically only
microseconds. However, on some systems
there is no choice but to use the same
clock source as for
currentTimeMillis() - fortunately this
is rare and mostly affects old Linux
systems, and Windows 98.