Оставшиеся дни до даты не отображаются правильно
Итак, я создал функцию, которая показывает количество дней до даты в будущем... Это правильно, пока количество дней не превысит 9 дней... если кажется, что через это число показывает случайное количество дней... Пожалуйста, смотрите мой код ниже:
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
это модель данных, содержащая информацию... String inputDateString = UIDM.get(position).date;
возвращает значение 01-10-2018 23:59
,
4 ответа
Обратите внимание, что Calendar.DAY_OF_MONTH
возвращает день месяца от 1 до 31
поэтому он рассчитает разницу между двумя днями (число от 1 до 31), как если бы они были в одном месяце
Я бы предложил использовать временные метки, а затем преобразовать результат из миллисекунд в число дней, например:
long oneDay = 24 * 60 * 60 * 1000; // in milliseconds
long diff = day.getTime().getTime() - calCurr.getTime().getTime();
long numberOfDays = diff / oneDay;
тогда вы можете изменить его на String
с Long.toString(numberOfDays)
java.time
java.time, современный Java-интерфейс даты и времени, имеет методы для вычисления количества дней между двумя датами. Так что не стоит делать этот расчет самостоятельно. Это подвержено ошибкам.
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);
}
Запустив этот фрагмент прямо сейчас (уже 13 сентября в Новой Зеландии), я получил такой вывод:
Осталось дней: 18
Пожалуйста, замените свой правильный часовой пояс, если это не Тихий океан / Окленд.
Ответ LaVepe уже хорошо и правильно объяснил, что пошло не так в вашем коде, поэтому я не буду повторять это.
Дата и время занятий вы использовали - Calendar
а также SimpleDateFormat
- давно устарели и всегда были плохо спроектированы. Есть способ получить Calendar
считать дни, 1 день за раз, но это не очень подходит для этого. SimpleDateFormat
печально известен проблемами, которые это вызвало для многих программистов. Я рекомендую вам вообще избегать этих классов и использовать вместо этого java.time.
Вопрос: Могу ли я использовать java.time на Android?
Да, java.time
прекрасно работает на старых и новых устройствах Android. Это просто требует как минимум Java 6.
- В Java 8 и более поздних версиях и на более новых устройствах Android (от 26 уровня API, как мне говорят) современный API поставляется встроенным.
- В Java 6 и 7 получите ThreeTen Backport, бэкпорт новых классов (ThreeTen для JSR 310; см. Ссылки внизу).
- На (более старой) версии Android используется версия Android ThreeTen Backport. Это называется ThreeTenABP. И убедитесь, что вы импортируете классы даты и времени из
org.threeten.bp
с подпакетами.
связи
- Ответ от LaVepe
- Учебник Oracle: Дата и время, объясняющие, как использовать
java.time
, - Запрос спецификации Java (JSR) 310, где
java.time
был впервые описан. - ThreeTen Backport проект, бэкпорт
java.time
в Java 6 и 7 (ThreeTen для JSR-310). - ThreeTenABP, Android-версия ThreeTen Backport
- Вопрос: Как использовать ThreeTenABP в Android Project, с очень подробным объяснением.
Чтобы получить интервал дней между двумя днями, вы можете сделать так:
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;
}
Выше функция успешно протестирована, измените ее в соответствии с вашими требованиями.
Попробуйте этот метод
/**
*
* @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;
}