In my android program I am using two Calendar instances to get the elapsed time in my program, first I set a level starting time as follows:
level_Start_TimeCal = Calendar.getInstance();
and in my thread I am calculating elapsed time as follows:
level_current_TimeCal = Calendar.getInstance();
gameTime = level_current_TimeCal.getTimeInMillis()- level_Start_TimeCal.getTimeInMillis();
dsecs = (gameTime / 1000)%60;
dminutes = (gameTime / (60 * 1000))%60;
dhours = (gameTime / (60 * 60 * 1000))%60;
Recently I came to read the following:
Calendar's getInstance method returns a Calendar object whose calendar
fields have been initialized with the current date and time
I want to know if I am in right path?
Am I creating an object each time the thread running?
If yes is there any alternative to avoid creating unwanted objects and calculating elapsed time?
Final question: at some point I want to reset the time in my restart method I reset it by just calling getInstance in my reset method as follows:
public void restart() {
level_Start_TimeCal = Calendar.getInstance();
}
Is this the correct way to reset the Calendar?
The best way to calculate elapsed time is to use System.nanotime().
long start = System.nanoTime();
//do something
long end = System.nanoTime();
//to get the elapsed time, you can use the TimeUnit utility methods:
long elapsedInNanos = end - start;
long elapsedInSeconds = TimeUnit.SECONDS.convert(elapsedInNanos, TimeUnit.NANOSECONDS);
Note that it is not a useful method to access absolute time.
Related
I have created a simple application to do exercises and rehearsals in general, I'm trying trying to update a variable every second but I can't find a working way.
The code is this:
long milliSec = SystemClock.elapsedRealtime();
String upTime = String.format(Locale.getDefault(),
"%02d giorni, %02d:%02d:%2d",
TimeUnit.MILLISECONDS.toDays(milliSec),
TimeUnit.MILLISECONDS.toHours(milliSec) - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(milliSec)),
TimeUnit.MILLISECONDS.toMinutes(milliSec) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(milliSec)),
TimeUnit.MILLISECONDS.toSeconds(milliSec) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(milliSec)));
The upTime variable I am putting in an array of strings. Can anyone kindly help me overcome this little obstacle?
Thanks a lot to everyone :)
I am not sure what exactly is your question.
You have the system uptime rather than the current time
You want to update a variable every second.
You store the updated variable in an array of strings.
Which of the three do you want to change?
Format the current time into a readable string using SimpleDateFormat.
Format the uptime using Instant and Duration like
Instant startTime = Instant.now(); // to this once on application start
Duration d = Duration.between(startTime, Instant.now()); // do this evey second
String s = String.format("%s days and %sh %sm %ss", duration.toDays(),
duration.toHours() - TimeUnit.DAYS.toHours(duration.toDays()),
duration.toMinutes() - TimeUnit.HOURS.toMinutes(duration.toHours()),
duration.getSeconds() - TimeUnit.MINUTES.toSeconds(duration.toMinutes()));
Remaining is to execute the code every second. I recommend placing this code inside a Runnable:
Instant startTime = Instant.now();
while (true) {
Duration duration = Duration.between(startTime, Instant.now());
String s = String.format("%s days and %sh %sm %ss", duration.toDays(),
duration.toHours() - TimeUnit.DAYS.toHours(duration.toDays()),
duration.toMinutes() - TimeUnit.HOURS.toMinutes(duration.toHours()),
duration.getSeconds() - TimeUnit.MINUTES.toSeconds(duration.toMinutes()));
// place the string wherever you need it
Thread.sleep(1000);
}
then have it running in a background thread. It will not exactly go every second but the reported uptime will be dead right.
I'm trying to find the difference between current time value and a future time in HH:MM:SS format.
For example:
When date1 is "2017-05-11T20:30" and date2 is "2017-05-11T21:40", the output should be 01:10:00.
Here's the code I'm trying, wherein I'm trying to find the difference between current time and a future time value:
public void updateTimeRemaining() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm");
String currentTime = simpleDateFormat.format(new Date());
long difference = simpleDateFormat.parse(endTime).getTime() - simpleDateFormat.parse(currentTime).getTime();
if (difference>0) {
String hms = String.format("%02d:%02d:%02d", millisLeft/(3600*1000),
millisLeft/(60*1000) % 60,
millisLeft/1000 % 60);
textView.setText(hms); //setting the remaining time in a textView
}
}
I'm invoking the method updateTimeRemaining() every second so that the textview gets updated every second like a timer. The problem I'm facing is seconds value always returns 0. Instead I would like the seconds value to be updated every second like below:
01:50:45
01:50:44
01:50:43
01:50:42...
You could use
difference = simpleDateFormat.parse(endTime).getTime() - new Date().getTime();
in place of these lines of your code:
String currentTime = simpleDateFormat.format(new Date());
long difference = simpleDateFormat.parse(endTime).getTime() - simpleDateFormat.parse(currentTime).getTime();
This should work fine.
You can use CountDownTimer. Here is an example :
new CountDownTimer(30000, 1000) { // 30 seconds countdown
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
The Constructor is : CountDownTimer(long millisInFuture, long countDownInterval)
You are performing a subtraction of two values and taking action if the result is greater than 0. Since it is not, it means endTime is necessarily not in the future but is before currentTime.
Fix your endTime problem.
I got three suggestions.
To me the natural suggestion is you use the classes in java.time. They are much nicer to work with than the outdated Date and SimpleDateFormat that are built-in with your Android Java.
long endMillis = LocalDateTime.parse(endTime,
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm"))
.atZone(ZoneId.systemDefault())
.toInstant()
.toEpochMilli();
long difference = endMillis - System.currentTimeMillis();
The rest will be the same as in your code. To use LocalDateTime and DateTimeFormatter on Android you will need to get ThreeTenABP, it contains the classes.
I wish I could tell you to use Duration, another one of the newer classes. However, Duration doesn’t seem to lend itself well to formatting. This will change with Java 9 (not tested):
LocalDateTime endDateTime = LocalDateTime.parse(endTime,
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm"));
Duration diff = Duration.between(LocalDateTime.now(ZoneId.systemDefault()),
endDateTime);
if (! diff.isNegative()) {
String hms = String.format("%02d:%02d:%02d",
diff.toHoursPart(),
diff.toMinutesPart(),
diff.toSecondsPart());
textView.setText(hms); //setting the remaining time in a textView
}
Isn’t that beautiful and clear?
If you don’t want the dependency on ThreeTenABP, there is of course a fix to your code. It’s even a simplification. In your code you are formatting the new Date() that you are getting the current time from, without seconds, so they get lost, and then parsing it again, and finally getting its milliseconds since the epoch. Skip all of that and just get the current time from System.currentTimeMillis() just as in the first snippet above:
long difference = simpleDateFormat.parse(endTime).getTime()
- System.currentTimeMillis();
This will give you your seconds.
I am using Java Timer class for running certain task. For my program I will give starttime and endtime as parameters which will ask the java timer when to start and when to end the task.
While running my task, I want to get and check the difference between current time and endtime periodically and If current time equals endtime then cancel the task by calling timer.cancel() method.
My startTime and endTime parrameters time format are like this
String startTime = "12:00";
String endTime = "12:01";
SimpleDateFormat format = new SimpleDateFormat("HH:mm");
Date date1 = format.parse(startTime);
Date date2 = format.parse(endTime);
long difference = date2.getTime() - date1.getTime();
I want to check the current time is equal to endtime.
But I want to check the condition that the current time is equal to end time and call the timer.cancel()
May be, you just don't know how to get the endTime.
String startTime = "12:00";
SimpleDateFormat sDateFormat = new SimpleDateFormat(
"hh:mm");
String endTime = sDateFormat.format(new java.util.Date());
if (startTime.equals(endTime)) {
timer.cancel();
}
try, and good luck
It may not be the time problem..
If comparing two Strings, you'd better use equals()
Try this :
if(currentTime.equals(endTime)) {
timer.cancel();
}
You should use the "currentTime.equals(endTime)" function to compare strings, not the == operator.The ".equals" function checks the actual contents of the string, the == operator checks whether the references of both the objects are equal which is not valid in your case.
You want to check if the current time is equal to the end time - that is understood but to what level do you wish to check if it is equal - up to the minute, second or millisecond? Since if you compare by the millisecond or lower it is possible that you may never cancel even when the time may be same to the second.
If you want to check to the millisecond - just convert your end date to millis date.getTime() and subtract System.currentTimeMillis() - if the result is 0 it is same to the millisecond. If the difference is less than 1000 (1 * 1000) it is within the second. If it is less than 60000 (1 * 60 * 1000) it is within the minute.
I need to write a method that can only execute once every 24 hours. It grabs a string, called "lastCollection", then should parse it to some sort of time object. It should then get the current time, and check if it has a 24 hour difference from "lastcollection". If so, it should execute some code, and set lastCollection to a new readable time string. Whats the best way to go about doing this?
Is this called by something or is this something that needs to be ran once every 24 hours?
If Possible you can just sleep it. I'll need a code example to show you how to fit it in but.
In case of once a day On a Schedule
Get Time at start of method.
Perform Method
Get New Time
Get Difference in Start Time and Current Time
Sleep the remainder of the time until same start time of the next day.
OR
Need to check before Performing
Get Time at start of method save to variable
Every time this method is called check a difference in a value say Minutes(see below)
If it is greater than 24 then repeat the method
Date Diffs can be done like this:
Date lasttimeran = null;
Date now = null;
long diff = now.getTime() - lasttimeran.getTime();
long diffMinutes = diff / (60 * 1000);
//If block to check if it has been long enough >= ensures a diff of exactly 24 hours will still trigger the method to be ran
if (diffMinutes >= 1440) {
//Do Something
}
else{
//Do Nothing
}
Calendar expCal = Calendar.getInstance();
while (true) {
expCal.add(Calendar.HOUR, 24);
Date expirationDate = expCal.getTime();
Date currentDate = new Date();
if (currentDate.compareTo(expirationDate) == 0)
//Do your Work here
expCal = Calendar.getInstance();
}
can anybody suggest me to find interval between system time and user defined time as my hour =20 and minute =12.I just want to find interval between this two times and need to set this time for countdown timer
To get difference between any two date/calendar objects it's better to get time in milliseconds(long).
Calendar current = Calendar.getInstance();
Calendar usertime = Calendar.getInstance();
usertime.set(Calendar.HOUR_OF_DAY, 20);
usertime.set(Calendar.MINUTE, 12);
long diffInMilisecond = Math.abs(usertime.getTimeInMillis()-current.getTimeInMillis());
If you can use third party api, then Joda time will hold very good for the above scenario. See here
Why go through all the trouble of having the user enter in the time he wants instead of how long from the current time? It makes more sense when mapping to the idea of a countdown timer.
If you want to set a timer for a user specified time this is how I would do it.
//Get user input into variable hours, and minutes
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
//do stuff when countdown has happened
}, (((hours * 60) + minutes) * 60) * 1000)); //time in milliseconds to exec run
}
EDIT
If you simply want to calculate the difference in time when the user inputs hour and minute try the following:
//Get user input into variable hours, and minutes
Calendar cal = new GregorianCalendar();
//Assuming user inputs hour in 24 hour format and inputted time is in future
totalMinsDiff = (hours - cal.get(Calendar.HOUR_OF_DAY)) * 60 +
minutes - cal.get(Calendar.MINUTE);
countdownHours = totalMinsDiff / 60;
countdownMins = totalMinsDiff % 60;