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.
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 have been trying to figured out an algorithm to return a list of time based on a start time and end time and how many loop. For example the start time at 6 am and the end time at 10 pm and the looping number is 5 so I need to return 22-6 = 16 and 16/5 = 3.2 so I need to return
6:00:00
9:20:00
12:40:00
15:60:00
18:20:00
21:40:00
I need to return such these values. (Note, the return value I wrote are not accurate but just for the purpose of demonstration)
The current code:
// List<Time> times(int looping){
long test(){
List<Time> result = new ArrayList<Time>();
String start = "06:00:00";
String finish = "22:00:00";
Time startTime = Time.valueOf(start);
Time endTime = Time.valueOf(finish);
long totalHours = endTime.getTime() - startTime.getTime();
return totalHours;
// return result;
}
Note: the long totalHours return a strange number not 16 and I'm not sure how to loop throw time and return the wanted values.
java.time
This is one of the places where java.time, the modern Java date and time API, excels. The method Duration::dividedBy does just want you want, dividing a span of time into a certain number of chunks.
List<LocalTime> result = new ArrayList<>();
String start = "06:00:00";
String finish = "22:00:00";
LocalTime startTime = LocalTime.parse(start);
LocalTime endTime = LocalTime.parse(finish);
Duration totalTime = Duration.between(startTime, endTime);
int subintervalCount = 5;
Duration subintervalLength = totalTime.dividedBy(subintervalCount);
LocalTime currentTime = startTime;
for (int i = 0; i < subintervalCount; i++) {
result.add(currentTime);
currentTime = currentTime.plus(subintervalLength);
}
System.out.println(result);
This outputs:
[06:00, 09:12, 12:24, 15:36, 18:48]
Where did the strange number of total hours come from?
the long totalHours return a strange number not 16 and I'm not sure
how to loop throw time and return the wanted values.
The Time class doesn’t define a getTime method. Instead you are calling the getTime method of the superclass java.util.Date, another poorly designed and long outdated class that we should no longer use. This getTime retunrs the count of milliseconds since the epoch of 1970-01-01T00:00:00 UTC, something that does not make sense for a time of day. I consider it likely that your subtraction yielded the number of milliseconds rather than the number of hours between your two times.
Edit: In case you’re curious and want to check: 16 hours equals 57 600 000 milliseconds. I obtained the number from TimeUnit.HOURS.toMillis(16).
Link
Oracle tutorial: Date Time explaining how to use java.time.
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 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();
}
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.