I am trying to make a Timer that will start counting from Date,
so every time i launch the app, the Timer will always be updated
for example if i start the timer at 20:00 22/11/18, tomorrow at 21:00 it will show 25:00:00.
I have only found how to do a CountdownTimer, or just a simple timer.
You can get the current time when you start the timer with:
long timerStart = System.currentTimeMillis();
And then when you want to show what the timer is at calculate it by doing
long timePassed = System.currentTimeMillis() - timerStart;
And that will give you the number of milliseconds since you started the timer. And to format it the way you want you can pass it into this function:
public static String convertMillisToHMmSs(long millis) {
long seconds = millis / 1000
long s = seconds % 60;
long m = (seconds / 60) % 60;
long h = (seconds / (60 * 60));
return String.format("%d:%02d:%02d", h,m,s);
}
Edit: As mentioned by the other answers, you will need to store the timerStart somewhere to keep track of it after the app is closed/reopened. I would recommend something like shared preferences you can look at this question to figure out how to do that
Unless you are willing to create an app that will run in background the whole time for few days (which would be highly unoptimized for an app of this complexity)
I think the best solution would be to store your start date (start timestamp) somewhere. Either in Room or in Shared Preferences and not to program your APP to increase or decrease your counter by one every second, than rather to calculate difference between start and current timestamp every second.
There are obviously a lot questions about performance but according to your question I guess that you are not concerned by this, and it will be a good practice for you to optimize this solution to be faster and more precise.
Agree above with Quinn however, somewhere you need to create a file that stores the current time. Otherwise every time app restarts the variable timerStart will reset.
So you need to create a file that stores the 'timerStart' so that every time you start, it updates from the value.
Related
Currently this is how I get time elapsed for a process to get completed.
long start = System.currentTimeMillis();
process();
long end = System.currentTimeMillis();
long duration = stop - start;
System.out.println(duration);
The problem I am facing currently is the process() gets interrupted(paused) by my pc's hibernation whenever there's no power(My work environment is outside so I have to be on battery) so that it can continue whenever I restart the pc when plugged. I am fully aware I would get a wrong duration if for example I am not able to restart for about 2hrs since the process got paused(during hibernation) as this would mean the extra 2hrs will be accounted for by the CPU clock via the CMOS battery backup whenever the line
long end = System.currentTimeMillis();
is reached. How would it be possible to get the exact duration irrespective of the process being paused severally.
So your question is "how much wall clock time was taken by the process, without time spent in hibernation". Well, wall clock time is easy to get, but you don't really have a chance to know whether hibernation happened or not.
However...
If your process is a set of discrete steps, you could do something like the following
List<Duration> durations = new ArrayList<>();
for(Step step : steps) {
Instant stepStart = Instant.now();
process(step);
durations.add(Duration.between(stepStart, Instant.now()));
}
long totalMillis = durations.stream()
.mapToLong(Duration::toMillis)
.filter(ms -> ms < 1000) // Cut off limit, to disregard hibernate steps
.sum();
This times each step separately, and if the time for a step takes more than 1 second, it's not taken into account in the total. You could also use an "average" time for those steps, so the end result would be a bit more realistic (of course this depends on the number of steps, the assumed runtime of a single step, etc.).
This only works if there is a good limit to what is "too much" time, and it provides a less accurate result. If you're doing something with BigInteger, it's likely that steps with larger values take more time, so a single cutoff value would not work (although you could consider some kind of dynamic cutoff value, based on the input).
Cheapest, easiest and best solution: run the code on a server.
Is there library in Android that can provide me the total spend time of a user in my application without using my own time count?
I believe that Android OS is counting all application use time the same way as they count battery use ,network, etc..
If my assumptions are right, What I need is this system count for my application use time.
You can use Fabric (https://fabric.io/) there's some a lot useful tools that you can use, it also can track Daily Active User, Crash Reporting, etc.
They also provide us easy integration step, just take few minutes to integrate our system with Fabric.
The general approach to this is to:
Get the time at the start of your benchmark, say at the start of main().
Run your code.
Get the time at the end of your benchmark, say at the end of main().
Subtract the start time from the end time and convert into appropriate units.
A simpler way is this.
long startTime = System.nanoTime();
.....your program....
long endTime = System.nanoTime();
long totalTime = endTime - startTime;
System.out.println(totalTime);
I am using freegeoip api to find out country name for each ip, but call limit is 15000 per hour .
How to process each file containing 15000 ips efficiently in an hour.
Is Thread.sleep work?
If they are taking 15 minutes to process, The rudimentary solution is to just take note of the start time. When the process is done, see how many milliseconds is left from the current time until the start time plus one hour.
long startTime = System.currentTimeMillis();
// do the requests
long currentTime = System.currentTimeMillis();
long timePassed = currentTime-startTime;
long millisInHour = 60*60*1000;
long timeToWait = millisInHour - timePassed;
Thread.sleep(timeToWait);
Other things you could consider is Timer.scheduleAtFixedRate() to fire off a file of 15,000 every hour. Better yet, use Quartz or a similar framework to schedule jobs every hour. If running on Linux, you might even schedule the program to run with 1 file every hour using cron. In this case you don't just have a Java process running all the time in the background on your machine.
Another option is to not use freegeoip.net, but use their software which is available here https://github.com/fiorix/freegeoip to then run your own server or integrate the functionality into your program.
iam trying to make a task to be executed EVERYDAY at 8am (example).
Currently what i have done is make a task, execute it automatically but only for a period of time (in this case 50 seconds) i want it to be executed every day at 8am.
my current code :
Timer time = new Timer();
certif_envia_notificacion st = new certif_envia_notificacion();
time.schedule(st, 0, 50000);
where certif_envia_notificacion is the task that i want to execute, and it does execute every 50 seconds.
Currently the only way i can figure this out is in the task certif_envia_notificacion ask for the time and execute if its 8am, but that seems like a huge waste of server resources, since ill have to execute the task at least 24 times a day.
Thanks in advance.
This is kind of a hack solution that I thought up, but feel free to give comments/feedback based on your requirements.
Basically, from my understanding you have a Java program that runs automatically when the computer starts up (if it restarts), and will then check every hour to see if it is the correct time to run the application. Why not keep it running this way, but instead of running every hour, calculate the time required to get to the next time required (e.g. 8PM the next day).
So for example, lets say you restart it at 3:15PM. When the java program runs, get it to get the current time (System.currentTimeMil...) and then calculate the time required to get to 8PM. You can do some simple math on this (e.g. 20 - current time = time required to wait) and if its negative, simply add 24 to it (e.g. if its 20 - 23, the answer is 24 - 3 = 21, thus wait 21 hours for the next 8PM).
This process can be used every time you run the code, or on startup. I'd recommend just creating a simple function to calculate the required sleep time.
What i finally did was execute the procedure every one hour and make a question of the hour and select the hour that i wanted, i know its not the best way but i needed to finish it fast....
Calendar cal = Calendar.getInstance();
int hour = cal.get(Calendar.HOUR_OF_DAY);
if(hour == DesiredHour){
//do stuff
}else if(hour == DesiredHour2){
//do stuff 2
}
Thanks for the comments.
I have a requirment to run a while loop the 5 min.
I looked for the timer api but I could not found to do this.
Can any one provide a code snipet for this.
Thanks
The easiest way will be to just check how much time has elapsed on each iteration. Example:
final long NANOSEC_PER_SEC = 1000l*1000*1000;
long startTime = System.nanoTime();
while ((System.nanoTime()-startTime)< 5*60*NANOSEC_PER_SEC){
// do stuff
}
This will run the loop, until more than 5 minutes have elapsed.
Notes:
The current loop iteration will always complete, so in practice it will always run for a bit more than 5 minutes.
For this application System.nanoTime() is more suitable than System.currentTimeMillis() because the latter will change if the computer's system clock is adjusted, thus throwing off the calculation. Thanks to Shloim for pointing this out.
This loop will run for 5 minutes. It will not be effected by changes made to the computer's date/time (either by user or by NTP).
long endTime = System.nanoTime() + TimeUnit.NANOSECONDS.convert(5L, TimeUnit.MINUTES);
while ( System.nanoTime() < endTime ){
// do whatever
}
Other methods like System.currentTimeMillis() should be avoided, because they rely on the computer date/time.
Because you are talking about the timer API I guess what you are after is a delay instead of a "loop running for 5min". If this is the case you could use something like Thread.sleep(..) which would allow to let the CPU do more usefull stuff that busy-waiting. Or at least save some energy and the planet.