How do I measure how long the program is executed - java

I am creating a Java Application where the OS's System Clock is adjusted from time to time. (so it's like a peer-to-peer NTP experiment)
I am looking for a Java construct that is something like a virtual clock where in I can still get the age of the application in milliseconds from the time it was executed. Because if I will always just use System.currentTimeMillis(), it might give me false age of the application.
Is there something like that? without actually creating another thread solely for it?

To calculte the elapsed time of your program you have multiple possibilities. Not all will fit your program because your system time could be change while your program is running.
currentTimeMillis()
With that method you get the current time of your system in millisecounds. If you want to calculate the runnning time of your program you could save the currentTime in a long variable. When you want the time the program is needed, you just simply subtract the currentTime now with your saved one.
Save the time when your program starts!
long start = System.currentTimeMillis();
Subtract the end time and the start time!
long need = System.currentTimeMillis() - start;
Keep in mind that if you change the system time you get a wrong time!
nanoTime()
With nanoTime you get the elapsed time of your Virtual Java Machine in nanosecounds. If you want to calculate the elapsed time, you have to do the same like with currentTimeMillis(). At the beginning you save the time and at the end you substract it.
Save the time when your program starts!
long start = System.nanoTime();
Subtract the end time and the start time!
long need = (System.nanoTime() - start) / 1000000; // divide to get millisecounds
Keep in mind that you get the right time, even if you change the system time, because you use the time of the Virtual Java Machine!
Difference
You only get the right elapsed time with System.nanoTime(). You should not use System.currentTimeMillis(), unless you do not mind that your result is wrong. currentTimeMillis() is to measure "wall-clock" time. When your system time is updateing, you simply get a wrong time. nanoTime() is actully mad for that, that you calculate the elapsed time.

No way to do this directly in Java, the only solution to this is to record the time differences applied to the system clock and takes this into account in your application.
Of course this depends greatly on the underlying operating system and the tools used to adjust the system clock.

Related

JavaFX - Using time as a variable for a line chart

I am essentially trying to create a visual representation of the memory being used in my program. I have created a LineChart and set the Y-axis to be Memory used, and the X-axis to be time. My question is, what is the best way to set up a timer, so that incoming data about memory usage can be paired with the current time.
By this I mean, I want to start a timer when the window displays, and continue to count up (possibly with millisecond precision), and so I can say that after the program has been running for this long, this is the amount of memory used.
What would be the best resources to use for this task?
The best bet would probably just to use System.currentTimeMillis(); and set it to a variable when you start the count, then call it again and compare the saved value with the new timer to get your time.
so..
Long startTime = System.currentTimeMillis();
//Do whatever stuff
long timeElapsed = System.currentTimeMillis() - startTime;
One thing to keep in mind with this though, is currentTimeMillis() is platform dependent on how granular it is. On unix-based you get 1 ms. of a granularity minimum, I think on windows it's 50. So if you need something more accurate than 50 ms. time steps, you might need a different method.
You must use a StopWatch to measure the time. Please go through the following links
https://stackoverflow.com/a/8255766/1759128
There are many alternatives in different answers of the question. You can use any of them !

System.currenTimeInMillis() vs System.nanoTime()

I know that System.nanoTime() is now the preferred method for measuring time over System.currentTimeInMillis() . The first obvious reason is nanoTime() gives more precise timing and the other reason I read that the latter is affected by adjustments to the system’s real-time clock. What does "getting affected by systems real-time clock " mean ?
In this case I've found following blog post excerpt useful:
If you are interested in measuring absolute time then always use
System.currentTimeMillis(). Be aware that its resolution may be quite
coarse (though this is rarely an issue for absolute times.)
If you are interested in measuring/calculating elapsed time, then
always use System.nanoTime(). On most systems it will give a
resolution on the order of microseconds. Be aware though, this call
can also take microseconds to execute on some platforms.
Clocks and Timers - General Overview by David Holmes
Since System.currentTimeMillis() is relying on the systems time of day clock, adjustments to the time are legitimate, in order to keep it on time.
What means adjustments here? Take for instance a look at the description of CLOCK_REALTIME from Linux:
System-wide clock that measures real (i.e., wall-clock) time.
Setting this clock requires appropriate privileges. This clock is
affected by discontinuous jumps in the system time (e.g., if the
system administrator manually changes the clock), and by the
incremental adjustments performed by adjtime(3) and NTP.
Just check the JavaDoc of the methods:
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. ..."
System.currentTimeMillis()
"... Returns the current time in milliseconds. ..."
So as you can see if the system time changes during the measurement using the System.currentTimeMillis(), the interval you measure will change too. However, it will not change when measuring the interval using the System.nanoTime() method.
It means that the value that System.currentTimeMillis() returns is obtained from the internal clock of the machine. If a sysadmin (or NTP) changes the time, for example if the clock is found to be running 5 minutes fast and the sysadmin goes and corrects it, System.currentTimeMillis() will be affected. This means that you can even see the value decrease, and if you use it to measure intervals the timings can be off. You may even measure negative timings.
System.nanoTime() on the other hand returns a value that is derived from some internal CPU counter/clock. The time measured by this clock cannot be changed by any user or program. This means that it will be more reliable for timing. But the CPU clock is reset on poweroff so it's not useful for finding the current "wall-clock" time.

Java timing, System.nanoTime() batter than System.currentTimeMillis() but does it persist over sleep?

I am trying to implement a timer, it may be used for short (seconds) events, or longer (hours, etc) events.
Ideally it should persist over periods when the CPU is off, for example, battery has died. If I set the start time using System.currentTimeMillis() and end time using the same function, it works in almost all cases, except during periods like leap seconds, leap years, daylight savings time changes, etc... Or, if the user just changes the time (I've verified this). This is on an Android system, btw.
Instead, if I used System.nanoTime(), in addition to potentially being more accurate, it won't have the usual "hard time" issues with time changes, etc. My question is, does System.nanoTime() measure nanoseconds from some arbitrary time, in "hard time"? I'm not sure what the proper term is, but for example, will System.nanoTime() ran at X, then X+1 hour later, the system is shut off (dead battery on Android device, for example), then X+10 hours, the system is started, will running System.nanoTime() at this point return 10 hours? Or will it return 1 hour (since the "counter" that nanoTime uses may not be running when system is off/asleep?).
android.os.SystemClock.elapsedRealtime() - milliseconds since the system was booted including time spent in sleep state. This should be your best bet.
I dont think you can measure the switched off time in android.
For more info it might be better to check android system clock page. http://developer.android.com/reference/android/os/SystemClock.html
It is undefined:
"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."
For simplicity, we'll say when you run it at time X, the origin is X (this is allowed). That means it will return 0 then, and within the VM instance, time will then elapse at the same rate as a normal clock.
When you use Thread.sleep, that doesn't change the VM instance, so it isn't treated specially.
However, after the device is rebooted, you're in a different VM instance. Therefore, X is no longer guaranteed to be the origin.

System.currentTimeMillis() is a good choice for this?

I'm still not sure how System.currentTimeMillis() work, but I want to use it for a game server to handle Banned accounts.
For example, in data base I will have a "bannTime" which will equal (System.currentTimeMillis() + How_much_time_to_ban_in_ms ) in the user's data.
When the user will login, it will always check if it's OK using this:
if(bannTime==-1)return;
if(System.currentTimeMillis()>bannTime){
// It's ok you can long in
removeBanFromDataBase();
}else{
// You can not login, you have to wait: (bannTime - System.currentTimeMillis())
return;
}
What I need to know is:
Is it safe to use System.currentTimeMillis() like this as long as the code will always run on one machine ? Even if I reboot the machine, System.currentTimeMillis() will keep incrementing and never go back or start from zero ? Never ?
And what If I change the local time and date on the machine, System.currentTimeMillis() will change too ?
System.currentTimeMillis() will never reset to 0. It is the number of milliseconds since the Epoch, way back at midnight, January 1, 1970.
This approach is fine, and it's often easier to do maths with milliseconds, as you're finding out.
Ref: http://download.oracle.com/javase/6/docs/api/
edit: good point Spycho, the currentTimeMillis() response is based on the system clock, not magic, so changing the system time back by a couple of days would make the number decrease. But not in normal practice.
If you're using time to ban users, you will probably want to use an NTP service to keep your system clock correct (if you're not already).
System.currentTimeMillis() may go back (or leap forward) if the system clock is changed.
If this code is running on the server side you should be fine.
Due to leap seconds (or manual clock changes) the time on the server can change, but it shouldn't change by such a large amount that it actually matters if the ban is revoked too early.
You should, of course, ensure that the server is set to get its time via NTP, so that it's always as accurate as possible, and correctly set on reboot.
you could use a combination of that in addition to writing a file on the system and storing the timestamp/related information in the file
System.currentTimeMillis() is always the actual time, in milliseconds since midnight 1st January 1970 UTC, according to the local system. If you change the time on the machine, the output of System.currentTimeMillis() will also change. The same applies if you change the machine's timezone but leave the time unchanged. System.currentTimeMillis() will never reset to zero (unless you change the machine's time to be whatever the time was in the machine's timezone at 00:00:00.000 on 1st January 1970).
System.currentTimeMillis() should be fine for what you want to do.
You may like to set a `reboot counter (or program restart counter),' which is persistent (in db or file), to distinguish time-stamps recorded in different boot sessions.
And then record your time-stamp by the combination of System.currentTimeMillis() and the counter's value
When the reboot counters are different for two time-stamps, you may deal it differently from normal cases. Maybe launching a time synchronizing routine or something.
When using System.currentTimeMillis() you are getting the time of the System, in other words the time of the machine you are running your code on. So when you restart your machine, you will still get its time that will increment even when the machine is turned off for sure.
But when you change the time of the machine, System.currentTimeMillis() will get you the new time, the time you changed. So when the time is changed you will get wrong time.
I used this in many classes without holding the matter of changing the clock. You can just use it with only this risk. But I find it a very good choice to work on.
An alternative would be to use System.nanoTime() because a) its more accurate and b) its monotonically increasing. However its slightly more cumbersome to work in nano-seconds, and its highly unlikely to make any real difference, unless your system clock varies wildly by seconds or more. (In which case you are likely to have other problems)
just test this code.
change time while running this code.
System.currentTimeMillis() stops printing out when system time is set back.
it starts printing again when time > time_before_setting_back
while (true){
System.out.println(System.currentTimeMillis());
try {
Thread.sleep(1000);
} catch ( InterruptedException e ) {
e.printStackTrace();
}
}

How to get time delta independently from system time?

I'm writing a simple timer in Java. It has Start and Stop buttons, along with a text view showing how much time has passed since the timer was started.
It's implemented by setting initial time with System.currentTimeMillis() and updating current value each second in a loop.
The problem is that if I change system time while the timer is running, the whole measurement fails. E.g., if I set time back one month, the timer shows negative value as currentTimeMillis() now returns less value than initial.
So, how do I calculate time delta which would be independent from the system time? It would be also great to make this solution cross-platform.
Use:
System.nanoTime()
This should do it. It doesn't take the system time into account, and can only be used to measure elapsed time. Which is what you want. You need to divide by 1 million to get the elapsed milliseconds. See also the Javadocs.
System.nanoTime();
From 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.
Use time web services . for example this or this or this
You can install demon like NTP, system time jumping in any directions has a lot of issues and can lead to quite a lot of other problems.
System.nanoTime() not necessarily depend on the system clock - but it can - just make sure the system time is correctly progressing.
Modifying system time is a privileged operation, so it someone does that they shall know better.
Here is a bug 13 years of age regarding the same case: http://bugs.sun.com/view_bug.do?bug_id=4290274
HTH

Categories

Resources