Reputation:
I have two calendar dates where i am getting the difference between in days, hours, and minutes.
This works perfectly if the end date is greater than the start date. What doesnt work is if the start date is the same day of week as the end date, but an earlier time than the end date. For example: end date 2:20 pm Saturday, and start date is 7:20 pm on saturday. It calculates it at like 0days, and 5 hours. But, it should be more like 7 days.
Here is the code
long t1 = curCal.getTimeInMillis();
long t2 = setCal.getTimeInMillis();
if(t2 < t1){
days = t1-t2;
}else{
days = t2-t1;
}
long toDays = TimeUnit.MILLISECONDS.toDays(days);
long toHours = TimeUnit.MILLISECONDS.toHours(days) % 24;
long toMinutes = TimeUnit.MILLISECONDS.toMinutes(days) % 60;
String toastMessage = String.format(" %d Days %d Hours %d Minutes", toDays, toHours, toMinutes);
Toast.makeText(context, "ALARM in" + " " + toastMessage , Toast.LENGTH_LONG).show();
How can i handle the case where the end date is the same day as the start date, but the end date is a time before the start date?
Thanks
EDIT
I think i solved my problem. I am adding it for anyone else having the same issue. if end date = startdate(same day) add 7 to the calendar object for enddate. psuedocode
if (enddate == startdate)) {
enddate.add(Calendar.DAY_OF_YEAR, 7);
}
Upvotes: 0
Views: 1078
Reputation: 86296
ZoneId zone = ZoneId.of("Europe/Busingen");
DayOfWeek alarmDay = DayOfWeek.SUNDAY;
LocalTime alarmTime = LocalTime.of(14, 20);
ZonedDateTime now = ZonedDateTime.now(zone);
ZonedDateTime alarmDateTime = now.with(alarmDay).with(alarmTime);
if (alarmDateTime.isBefore(now)) {
alarmDateTime = alarmDateTime.plusWeeks(1);
}
Duration difference = Duration.between(now, alarmDateTime);
String toastMessage = String.format(" %d Days %d Hours %d Minutes",
difference.toDaysPart(), difference.toHoursPart(), difference.toMinutesPart());
System.out.println(toastMessage);
Running just now (Sunday 22:03:17 in Büsingen) I got:
6 Days 16 Hours 16 Minutes
I believe that I am contributing the answer that is not only the modern one but also the more robust one.
Calendar
class is long outdated and by today’s standards poorly designed. Instead I use and recommend java.time
, the modern Java date and time API.ZonedDateTime
objects minimizes surprises here. It does require you to fill in your desired time zone where I put Europe/Busingen since summer time transitions are time zone specific.Calendar
, a date and time, for a weekly recurring alarm seems a bit funny. What you need is a day-of-week and a time of day, so I use that. java.time
offers the classes needed, the DayOfWeek
enum and the LocalTime
class.I am in fact so modern that I am using the toXxxPart
methods of the Duration
class that were introduced in Java 9. For formatting the Duration
if you are not yet using Java 9 you will need to subtract first the days from the duration to get the hours: use the minusDays
method. Then do similarly with minusHours
to get the minutes.
long toDays = difference.toDays();
difference = difference.minusDays(toDays);
long toHours = difference.toHours();
difference = difference.minusHours(toHours);
long toMinutes = difference.toMinutes();
Yes, java.time
works nicely on older and newer Android devices. It just requires at least Java 6.
org.threeten.bp
with subpackages.java.time
.java.time
was first described.java.time
to Java 6 and 7 (ThreeTen for JSR-310).Upvotes: 1
Reputation: 5294
Reading your question another way, if t1
is the start date and t2
is the end date, your logic does not include the case where t1 < t2
and t2 - t1
< 1. In this case, you need to add 7 to the number of days. Something like:
long t1 = curCal.getTimeInMillis();
long t2 = setCal.getTimeInMillis();
if(t2 < t1){
days = t1-t2;
}else{
days = t2-t1;
if (days < 1) {
days += 7;
}
}
All of this can be simplified to
days = Math.abs(t1 - t2);
if (days < 1 && t1 < t2) {
days += 7;
}
Upvotes: 0