Оставшиеся дни до даты отображаются неправильно

Хорошо, поэтому я создал функцию, чтобы показать количество дней до даты в будущем... Это правильно, пока количество дней не превышает 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.


person astric mobiles    schedule 12.09.2018    source источник
comment
Что такое УИДМ?   -  person Prashanth Verma    schedule 12.09.2018
comment
UIDM — это модель данных, содержащая информацию... 'String inputDateString = UIDM.get(position).date; возвращает значение '01-10-2018 23:59'   -  person astric mobiles    schedule 12.09.2018
comment
В качестве отступления подумайте о том, чтобы выбросить давно устаревший и заведомо неприятный SimpleDateFormat и друзей и добавить ThreeTenABP на свой Android. проект, чтобы использовать java.time, современный API даты и времени Java. С ним намного приятнее работать.   -  person Ole V.V.    schedule 12.09.2018
comment
Хорошо, спасибо за рекомендацию, я посмотрю,   -  person astric mobiles    schedule 12.09.2018
comment
К вашему сведению, проблемные старые классы даты и времени, такие как java.util.Date, java.util.Calendar и java.text.SimpleDateFormat, теперь унаследованы, вытеснены java.time классы. Большая часть функций java.time обратно перенесена на Java 6 и Java 7 в ThreeTen-Backport. Дальнейшая адаптация для более ранней версии Android в ThreeTenABP проект. См. Как использовать ThreeTenABP….   -  person Basil Bourque    schedule 13.09.2018


Ответы (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)

person LaVepe    schedule 12.09.2018
comment
Сработало отлично... Большое спасибо за объяснение того, как работает Calendar.DAY_OF_MONTH. Большое спасибо. - person astric mobiles; 12.09.2018
comment
Хорошее объяснение. Предлагаемое вами решение является низкоуровневым. Я бы предпочел использовать библиотечные методы для вычисления разницы. - person Ole V.V.; 12.09.2018
comment
Этот ответ неверный. В сутках не всегда 24 часа. Они могут быть 23, 23,5, 24, 25 или многие другие числа часов. - person Basil Bourque; 13.09.2018
comment
@BasilBourque прав. Если вы измерите дельту в днях между датой в зимнее время и датой в летнее время, предложенный код не сработает. - person Meno Hochschild; 13.09.2018

Java.время

java.time, современный API даты и времени 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

Пожалуйста, укажите правильный часовой пояс, если это не Pacific/Auckland.

Ответ ЛаВепе уже хорошо и правильно объяснил, что пошло не так в вашем коде, поэтому я не повторяю это.

Используемые вами классы даты и времени — Calendar и SimpleDateFormat — давно устарели и всегда были плохо спроектированы. Есть способ заставить Calendar считать дни, по 1 дню за раз, но он не очень подходит для этого. SimpleDateFormat печально известен проблемами, которые он доставил многим программистам. Я рекомендую вам вообще избегать этих классов и вместо этого использовать java.time.

Вопрос: Могу ли я использовать java.time на Android?

Да, java.time прекрасно работает на старых и новых устройствах Android. Просто требуется как минимум Java 6.

  • В Java 8 и более поздних версиях, а также на более новых устройствах Android (начиная с уровня API 26, как мне сказали) современный API встроен.
  • В Java 6 и 7 используйте ThreeTen Backport, бэкпорт новых классов (ThreeTen для JSR 310; см. ссылки внизу).
  • На (старом) Android используйте версию ThreeTen Backport для Android. Он называется ThreeTenABP. И убедитесь, что вы импортируете классы даты и времени из org.threeten.bp с подпакетами.

Ссылки

person Ole V.V.    schedule 12.09.2018

Попробуйте этот метод

/**
         *  
         * @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;
    }
person Community    schedule 12.09.2018

Чтобы получить интервал дней между двумя днями, вы можете сделать так:

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;
}

вышеуказанная функция успешно протестирована, измените ее в соответствии с вашими требованиями.

person navylover    schedule 12.09.2018