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();
}
}
Related
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.
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.
when System.currentTimeMillis changed, what will be the possible reason?
say the currentTimeMillis changed 1 and 2 minutes hour only after 2 minutes. Related to day light saving?
One possible reason is the time is synced to the correct time , what will be the other possible reason?
I will just begin guessing - mainly I see 2 possible reasons:
You are writing the conversion from milliseconds since 01.01.1970 00:00UTC by yourself and did somwhere a mistake (we going to need the code)
There is some point when actually the return value makes a jump of 3600000 (such jumps will only happen if you change the System clock, or maybe you update the time using NTP)
System.currentTimeMillis(), according to its documentation, returns the the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC. So obviously it's changing rapidly all the time. The caveat is that it refers to wall clock, which could be adjusted anytime!
That is, it will jump an hour because of daylight saving time an arbitrary amount if someone or something - possibly an automated NTP synchronizer - simply adjusts the computer's clock or date. If you need to measure how long something takes, you should use a timer, e.g. System.nanoTime(), which is guaranteed to change monotonically, not a clock (which is supposed but not guaranteed to refer to some fixed point).
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
I am looking at the idea of a Java project that detects when the computer clock has been changed. The idea is to record the date and time on the computer clock and store it in a file. I then want to be able to run rules on it that shows a message if the clock has been changed. I am also looking at incorporating rules such as "Allowing no more than 5 minute changes". This is to allow convenience of changing the time by the odd minute.
I also need to incorporate the changes that the clock makes. E.g., going forward an hour or back an hour at certain times of the year (British Time).
I am not sure if there is already a Java system that does this that I could look at but I literally don't know where to start with this.
Java gets all it's time/date information from the system clock anyway, so there's no way of knowing if the underlying system clock has been changed. If you take the date and time and store it in a file - that will detect if the time has been set back (i.e. - the time in the file is after the current time, and no DST has occurred) - but it can't detect if time has been set forward (i.e. - the time in the file is 2 hours before the current time - has 2 hours really elapsed, or has the user set the clock ahead by 2 hours while the program wasn't running?). The only way you could do something like this is use a known Time Server, and instead of saving the time in the file, save the offset between the time server and the local system clock.
If you can rely on the presence of a network connection, you could compare the time with the time from an internet time server (CBATG).
Simply convert the local time and a fetched time to the same time zone and store the difference. If the diff changes by more than the allowed amount of 5 minutes, you know it's been modified.
If I understand your question right, then what you are trying to do assumes that initially, the system clock is at the optimal state. Then, after every minute you retrieve the last entry in the file (either the last or the first, whatever method you chose) and make sure that the difference between the two times is either 60 seconds or any other time interval you choose.
Example:
At time 0, you place in the file 12:00:00
At time 1, you compare 12:01:00 (which you retrieve from the system clock) with 12:00:00 (which you retrieve from file)and deem that it is alright and write it to the file.
...
At some time n, you compare xx:yy:zz whose difference with the last entry is not 60 seconds, so a change has been detected.
...
I believe the rules you're talking about involves taking the last entry from the file and doing a comparison with the current time you retrieved from the system clock. Whether or not this is a good method however, is arguable.
First: The clock changes veeeery often. Try using java.util.Timer for updating. Calender is for your time system.
http://java.sun.com/javase/6/docs/api/ is your friend in this.
Start small, one step at a time. That's my advice.
A good place to use the Joda time library. In theory, you only need to check if the local timezone has moved between DST and non DST state - if you don't want to check for local time shifts.
I haven't tried this, but it might work to have a background thread which wakes up once a minute, gets the current time, and compares it to what it last saw. Theoretically, the difference should be very close to one minute. If it differs much from that, that would mean the clock changed.
You seem to be asking for two very different things:
When a user or system administrator causes the computer’s clock to be adjusted or corrected to a certain moment (either to set to the true current date-time or to another past/future date-time for either testing or nefarious purposes).
When the displayed hour-minutes change for an event such as Daylight Saving Time (DST).
Clock manipulations
For the first, no good simple way to do that. You could occasionally sample the current date-time, record it, then sample again later. You would do this in UTC to avoid mistaking DST autumn changes as a user/sysadmin alteration.
Example code using the java.time classes. Avoid the old outmoded non-java.time classes as they are poorly designed, confusing, and troublesome.
Instant now1 = Instant.now(); // Record, run again, compare.
String now1AsString = now1.toString(); // Ex: 2011-12-03T10:15:30.724Z
…
Instant now2 = Instant.now();
Boolean timeWentBackwards = now2.isBefore( now1 );
Of course you cannot use this technique for adjusting into the future, only the past. The clock is always moving into the future.
The only reliable way to detect molestation of the clock is to have more than one clock. You need have trusted access (connection) to a trusted clock, probably either a time server on your network or a time server on the Internet. Even then, having only a pair of clocks can be tricky. As the old sea-faring adage says, “Bring aboard one compass, or three.”.
DST roll-overs
Detecting DST changes should be irrelevant. The general best practice in handling date-time is to work in UTC. This includes most of your business logic, your data storage, and your data exchange.
Remember: The time-of-day rolling forward or backward with DST is meaningless -- time continued to flow, not warp, with the same number of seconds passing.