问题
Ok, so I've created a function to show the number of days until a date in the future... It is correct until the amount of days is over 9 days.. if over it seems to show a random number of days... Please see my code below:
public String daysTillExpire() {
String daysLeft = "";
int position = 0 ;
String inputDateString = UIDM.get(position).date;
Calendar calCurr = Calendar.getInstance();
Calendar day = Calendar.getInstance();
try {
day.setTime(new SimpleDateFormat("dd-MM-yyyy").parse(inputDateString));
} catch (ParseException e) {
e.printStackTrace();
}
if (day.after(calCurr)) {
String noumberOfDays = "Days left: " + (day.get(Calendar.DAY_OF_MONTH) - (calCurr.get(Calendar.DAY_OF_MONTH)));
daysLeft = UIDM.get(position).date + "\n(" + noumberOfDays+")" ;
}
else if (day.before(calCurr)) {
daysLeft = "Key Expired";
return daysLeft; }
return daysLeft;
}
UIDM
is a data model containing info... String inputDateString = UIDM.get(position).date;
returns the value 01-10-2018 23:59
.
回答1:
Note that Calendar.DAY_OF_MONTH
returns the day of the month between 1 and 31
so it will calculate difference between two days (number between 1 and 31) as if they were in the same month
I would suggest to rather use timestamps and then convert the result from millis to number of days like this:
long oneDay = 24 * 60 * 60 * 1000; // in milliseconds
long diff = day.getTime().getTime() - calCurr.getTime().getTime();
long numberOfDays = diff / oneDay;
then you can change it to String
with Long.toString(numberOfDays)
回答2:
java.time
java.time, the modern Java date and time API, has methods for calculating the number of days between two dates. So don’t bother doing this calculation yourself. It’s error-prone.
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd-MM-uuuu H:mm");
String inputDateString = "01-10-2018 23:59";
LocalDate today = LocalDate.now(ZoneId.of("Pacific/Auckland"));
LocalDate expiration = LocalDate.parse(inputDateString, dateFormatter);
if (expiration.isAfter(today)) {
String numberOfDays = "Days left: " + ChronoUnit.DAYS.between(today, expiration);
System.out.println(numberOfDays);
}
Running this snippet just now (already September 13 in New Zealand) I got this output:
Days left: 18
Please substitute your correct time zone if it didn’t happen to be Pacific/Auckland.
The answer by LaVepe has already explained nicely and correctly what went wrong in your code, so I am not repeating that.
The date and time classes you were using — Calendar
and SimpleDateFormat
— are long outdated and were always poorly designed. There is a way to get Calendar
to count days, 1 day at a time, but it’s not well suited for that. SimpleDateFormat
is notorious for the trouble it has caused for many programmers. I recommend you avoid those classes altogether and use java.time instead.
Question: Can I use java.time on Android?
Yes, java.time
works nicely on older and newer Android devices. It just requires at least Java 6.
- In Java 8 and later and on newer Android devices (from API level 26, I’m told) the modern API comes built-in.
- In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310; see the links at the bottom).
- On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from
org.threeten.bp
with subpackages.
Links
- Answer by LaVepe
- Oracle tutorial: Date Time explaining how to use
java.time
. - Java Specification Request (JSR) 310, where
java.time
was first described. - ThreeTen Backport project, the backport of
java.time
to Java 6 and 7 (ThreeTen for JSR-310). - ThreeTenABP, Android edition of ThreeTen Backport
- Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
回答3:
Try this method
/**
*
* @param token
* @param date1 present date
* @param date2 future date
* @return diff
*/
public float dateDiff(String token,Date date1,Date date2){
float diff=0;
//different date might have different offset
Calendar cal1=Calendar.getInstance();
Calendar cal2=Calendar.getInstance();
cal1.setTime(date1);
long ldate1 = date1.getTime() + cal1.get(Calendar.ZONE_OFFSET) + cal1.get(Calendar.DST_OFFSET);
if(date2==null)
cal2.setTime(new Date());
else
cal2.setTime(date2);
long ldate2 = date2.getTime() + cal2.get(Calendar.ZONE_OFFSET) + cal2.get(Calendar.DST_OFFSET);
// Use integer calculation, truncate the decimals
int hr1 = (int)(ldate1/3600000); //60*60*1000
int hr2 = (int)(ldate2/3600000);
int days1 = hr1/24;
int days2 = hr2/24;
int dateDiff = days2 - days1;
int yearDiff = cal2.get(Calendar.YEAR) - cal1.get(Calendar.YEAR);
float monthDiff = yearDiff * 12 + cal2.get(Calendar.MONTH) - cal1.get(Calendar.MONTH);
System.out.println("monthDiff 1" +monthDiff);
System.out.println(" days: ;;;;222 "+dateDiff);
float fbm = dateDiff ;
fbm = (float) MasterLibraryFunction.doubRound(fbm /30,2) ;
if(token.equals("d"))
{
diff=dateDiff;
System.out.println(" days: ;;;; "+dateDiff);
}
else if(token.equals("m"))
{
//diff= monthDiff;
diff =fbm;
System.out.println(" diff ---------->: ;;;; "+fbm);
}
/*******day wise diff *******/
return diff;
}
/**
* @category Decimal point round
* @param val
* @param places
* @return Rounded Value to given place
*/
public static double doubRound(double val, int places) {
long factor = (long)Math.pow(10,places);
val = val * factor;
long tmp = Math.round(val);
return (double)tmp / factor;
}
回答4:
To get interval days between two days, you could do like this:
public long daysTillExpire() {
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
String dateInString = "01-10-2018 23:59";
Date date = null;
try {
date = sdf.parse(dateInString);
} catch (ParseException e) {
e.printStackTrace();
}
Calendar expiredCalendar = Calendar.getInstance();
expiredCalendar.setTime(date);
long msDiff = expiredCalendar.getTimeInMillis() - Calendar.getInstance().getTimeInMillis();
long daysDiff = TimeUnit.MILLISECONDS.toDays(msDiff);
return daysDiff;
}
above function is tested successfully, modify it according to your requirment.
来源:https://stackoverflow.com/questions/52293042/remaining-days-to-a-date-is-not-showing-correctly