What is the equivalent for this C# code in Java?
int tick = 0;
tick = Environment.TickCount;
There's no standard way to get the system up time in Java. If you know that you're on a Unix-like system, you can use:
Runtime.getRuntime().exec('uptime');
Or you can read the system file:
new Scanner(new FileInputStream("/proc/uptime")).next();
On some systems, this will also be the value returned by System.nanoTime(), but there's no guarantee about the origin for System.nanoTime() (or even that the return value will be positive).
If the only reason you want this is to measure elapsed time, you can use System.nanoTime() or, if you want to measure elapsed wall clock time (including any adjustments that might have been made while doing the timing), use System.currentTimeMillis().
As #TedHopp mentions, one possibility is to use System.currentTimeMillis(). In my case I wanted a "tick count" in seconds, not milliseconds. Here's what I'm currently using for the Java version of a corresponding C# method.
// Static field used by the tickCountInSeconds() method
private static long _firstCallTimeSeconds = 0;
...
/**
* Method to get an arbitrary constantly increasing time in seconds, i.e., a time in seconds that
* can be used to compare the relative times of two events, but without having any other meaning.
*
* The .Net version of this method uses the Windows "tick count" facility, but since that doesn't
* exist in Java we fake it by getting the system (Unix-style) time in milliseconds and
* converting it to seconds. But to avoid the "year 2038 problem" (or to avoid criticism for
* creating a year 2038 vulnerability) the time of the first call is saved in a static field and
* subtracted from the returned result.
*/
private synchronized static int tickCountInSeconds() {
long currentTimeSeconds = System.currentTimeMillis() / 1000L;
if (_firstCallTimeSeconds == 0) {
_firstCallTimeSeconds = currentTimeSeconds;
}
return (int)(currentTimeSeconds - _firstCallTimeSeconds);
}
Related
I want to attach a timestamp whenever an event happens in my application. Let's assume that a client creates a Event object and I want to attach a creation timestamp to the Event object. I can do this using the System.currentTimeMillis() within the constructor. This works fine if the Event objects are created no faster than once every millisecond. In this case each Event object gets a different value from System.currentTimeMillis() and hence the Event objects are sequenced.
However if the Event objects need to be created a rate that is faster than one object per millisecond, then my logic breaks. Depending on the rate of object creation 2 or more Event objects end up having the same creation timestamp (since System.currentTimeMillis returned the same value when called in quick succession)
Now how do I sequence the Event objects in this case? I am aware of the System.nanoTime() but that's not related to the epoch.
I am open to storing the creation timestamp within the Event class split into 2 instance variables - creationTimeInMS (long) and creationTimeInNS (long)
I do not want to java.sql.Timestamp which does support nano second precision
Is there anyway I could leverage the System.nanoTime to provide sequencing of the event objects?
Note - It is guaranteed that the event will not get created faster than 1 per nanosecond. Hence nanosecond precision will suffice
The code that I have using is as below
class Event {
private long timestamp
public Event() {
...
timestamp = System.currentTimeMillis()
}
So if the Event constructor is called by multiple threads at a rate faster than 1 per millisecond, then two (or more) Event objects get the same timestamp.
The System.nanoTime() is supposed to return unique number if called no faster than once every nano second. However I am not sure how I could use this number in conjunction with the timestamp. Do I add this to the timestamp to generate a nano second precision time?
It is hard to achieve that with relying on the wall clock, times are gonna collide and nano second resolution is hard to achieve in practice, a quick solution is to add a wrapper around the time that remembers its last value. This wont work in a distributed environment of course.
static class MonotonicClock{
private long last;
public MonotonicClock(){
last = System.currentTimeMillis();
}
public synchronized long getNext(){
long current = System.currentTimeMillis();
if(last < current){ // last seen is less than "now"
last = current;
}else{
last++; //collision, overclock the time
}
return last;
}
}
In a distributed system, things are more complicated. You might need to look at Lamport timestamps and Vector Clocks for that.
Given the following Java code:
class Tester
{
public static void main(String[] args)
{
System.out.println((System.nanoTime()/1000));
System.out.println(System.currentTimeMillis());
}
}
It gave an output of
2626051678558
1377785791569
I was expecting a little difference between the two but I was wrong.
Do you have any idea guys why it behaved like that?
Read the method's javadoc
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 origin
time (perhaps in the future, so values may be negative). The same
origin is used by all invocations of this method in an instance of a
Java virtual machine; other virtual machine instances are likely to
use a different origin.
nanoTime() is not showing you the time.
long currentTimeMillis = System.currentTimeMillis();
long nanos = TimeUnit.MILLISECONDS.toNanos(currentTimeMillis);
System.out.println(nanos);
System.out.println(TimeUnit.NANOSECONDS.toMillis(nanos)*1000000);
nanoTime(), as the java doc says, is a precision timer. currentTimeMillis() is NOT A TIMER, it is the "wall clock". nanoTime() will always produce positive elapsed time, currentTimeMillis will not (e.g. if you change the date, hit a leap second, etc.)
If you're on Android, nanoTime is affected by deep sleep modes. Use SystemClock.elapsedRealtime() (which returns msec) instead
I am using system.nanoTime in my app and I calculate time relative to a starttime.
My app ran very well until I copied it to a new computer and on it the nano time gives me slower values.
I wrote a simple app just to make sure.
the nano time is compared to the system time.
It shows the same values in other computers except my new one . any suggestions?
Here is my code:
First I have
private long initNanoTime = System.nanoTime();
private long initTime = System.currentTimeMillis();
than I loop a thread that runs every second:
long timeUsingNanoTime = initTime + (System.nanoTime() - initNanoTime) / 1000000;
long timeUsingMilis = System.currentTimeMillis();
long nanotimeOffset = Math.abs(timeUsingNanoTime - timeUsingMilis);
if (nanotimeOffset < 100l) ? print("close") : print(far);
Edit : I am using nano because I need to handle even ts that occur in nano time and print to a log the nano time which it was received in
It's like the Java API docs say about System.nanoTime():
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 origin
time (perhaps in the future, so values may be negative). The same
origin is used by all invocations of this method in an instance of a
Java virtual machine; other virtual machine instances are likely to
use a different origin.
This method provides nanosecond precision, but not necessarily
nanosecond resolution (that is, how frequently the value changes) - no
guarantees are made except that the resolution is at least as good as
that of currentTimeMillis().
It does not provide any coupling with the timestamp (currentTimeMillis) and does not provide a fixed resolution.
In your case it seems that Java now has a higher resolution timer available than before, and so does not need to use the system time.
I am making a call to a method by passing ipAddress and it will return back the location of ipAddress like Country, City, etc etc. So I was trying to see how much time it is taking for each call. So I set the start_time before making call to method and end_time after making a call. So sometimes I get difference as 0. And resp contains the valid response.
long start_time = System.currentTimeMillis();
resp = GeoLocationService.getLocationIp(ipAddress);
long end_time = System.currentTimeMillis();
long difference = end_time-start_time;
So that means sometimes it is taking 0 ms to get the response back. Any suggestions will be appreciated.
Try this
long start_time = System.nanoTime();
resp = GeoLocationService.getLocationByIp(ipAddress);
long end_time = System.nanoTime();
double difference = (end_time - start_time) / 1e6;
I pretty much like the (relatively) new java.time library: it's close to awesome, imho.
You can calculate a duration between two instants this way:
import java.time.*
Instant before = Instant.now();
// do stuff
Instant after = Instant.now();
long delta = Duration.between(before, after).toMillis(); // .toWhatsoever()
API is awesome, highly readable and intuitive.
Classes are thread-safe too. !
References: Oracle Tutorial, Java Magazine
No, it doesn't mean it's taking 0ms - it shows it's taking a smaller amount of time than you can measure with currentTimeMillis(). That may well be 10ms or 15ms. It's not a good method to call for timing; it's more appropriate for getting the current time.
To measure how long something takes, consider using System.nanoTime instead. The important point here isn't that the precision is greater, but that the resolution will be greater... but only when used to measure the time between two calls. It must not be used as a "wall clock".
Note that even System.nanoTime just uses "the most accurate timer on your system" - it's worth measuring how fine-grained that is. You can do that like this:
public class Test {
public static void main(String[] args) throws Exception {
long[] differences = new long[5];
long previous = System.nanoTime();
for (int i = 0; i < 5; i++) {
long current;
while ((current = System.nanoTime()) == previous) {
// Do nothing...
}
differences[i] = current - previous;
previous = current;
}
for (long difference : differences) {
System.out.println(difference);
}
}
}
On my machine that shows differences of about 466 nanoseconds... so I can't possibly expect to measure the time taken for something quicker than that. (And other times may well be roughly multiples of that amount of time.)
Since Java 1.5, you can get a more precise time value with System.nanoTime(), which obviously returns nanoseconds instead.
There is probably some caching going on in the instances when you get an immediate result.
From Java 8 onward you can try the following:
import java.time.*;
import java.time.temporal.ChronoUnit;
Instant start_time = Instant.now();
// Your code
Instant stop_time = Instant.now();
System.out.println(Duration.between(start_time, stop_time).toMillis());
//or
System.out.println(ChronoUnit.MILLIS.between(start_time, stop_time));
I do not know how does your PersonalizationGeoLocationServiceClientHelper works. Probably it performs some sort of caching, so requests for the same IP address may return extremely fast.
In the old days (you know, anytime before yesterday) a PC's BIOS timer would "tick" at a certain interval. That interval would be on the order of 12 milliseconds. Thus, it's quite easy to perform two consecutive calls to get the time and have them return a difference of zero. This only means that the timer didn't "tick" between your two calls. Try getting the time in a loop and displaying the values to the console. If your PC and display are fast enough, you'll see that time jumps, making it look as though it's quantized! (Einstein would be upset!) Newer PCs also have a high resolution timer. I'd imagine that nanoTime() uses the high resolution timer.
In such a small cases where difference is less than 0 milliseconds you can get difference in nano seconds as well.
System.nanoTime()
You can use
System.nanoTime();
To get the result in readable format, use
TimeUnit.MILLISECONDS or NANOSECONDS
I need to create a timestamp (in milliseconds) in Java that is guaranteed to be unique in that particular VM-instance. I.e. need some way to throttle the throughput of System.currentTimeMillis() so that it returns at most one results every ms. Any ideas on how to implement that?
This will give a time as close the current time as possible without duplicates.
private static final AtomicLong LAST_TIME_MS = new AtomicLong();
public static long uniqueCurrentTimeMS() {
long now = System.currentTimeMillis();
while(true) {
long lastTime = LAST_TIME_MS.get();
if (lastTime >= now)
now = lastTime+1;
if (LAST_TIME_MS.compareAndSet(lastTime, now))
return now;
}
}
One way to avoid the limitation of one id per milli-second is to use a micro-second timestamp. i.e. multiply currentTimeMS by 1000. This will allow 1000 ids per milli-second.
Note: if time goes backwards, eg due to an NTP correction, the time will just progress at 1 milli-second per invocation until time catches up. ;)
You can use System.nanoTime() for better accuracy
Although I tried below and each time it gives different values, it probably is not guaranteed to be unique all the time.
public static void main(String[] args) {
long time1 = System.nanoTime();
long time2 = System.nanoTime();
long time3 = System.nanoTime();
System.out.println(time1);
System.out.println(time2);
System.out.println(time3);
}
Another way is to use AtomicInteger/AtomicLong classes for unique numbers if the time is not important for you and you just need unique number, this probably is a btter choice.
While searching for a solution I came across ULIB
(Universally Unique Lexicographically Sortable Identifier)
https://github.com/huxi/sulky/tree/master/sulky-ulid/
It's not a long, but shorter then UUID.
A ULID:
Is compatible with UUID/GUID's
1.21e+24 unique ULIDs per millisecond (1,208,925,819,614,629,174,706,176 to be exact)
Lexicographically sortable
Canonically encoded as a 26 character string, as opposed to the 36 character UUID
Uses Crockford's base32 for better efficiency and readability (5 bits per character)
Case insensitive
No special characters (URL safe)
You could use System.nanoTime(), which is the most precise available system timer, and divide that by million to get milliseconds. While there are no formal guarantees on how often it's updated, I believe it's reasonable to assume that it updates way more (order(s) of magnitude) frequently than once per millisecond. Of course, if you create integer timestamps by less than millisecond interval, then they can't all be unique.
Note that the absolute value nanoTime() is arbitrary. If you want absolute time, calibrate it somehow, i.e. compare it to currentTimeMillis() when starting.
Could you perhaps make use of java.util.UUID and it's timestamp() and clockSequence()?
Method Summary
int clockSequence()
The clock sequence value associated with this UUID.
long timestamp()
The timestamp value associated with this UUID.
More details here: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/UUID.html