Как рассчитать число лет, месяцев и дней между двумя датами, используя Joda-Time - PullRequest
0 голосов
/ 30 ноября 2018

Я использую приведенный ниже код для вычисления количества лет, месяцев и дней между двумя датами, используя Joda-Time

public void getDateDiff(View view) {

    DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yyyy").withLocale(Locale.US);
    DateTime startDate = null;
    DateTime endDate = null;

    // expected output 23...2....29

    try {
        startDate = formatter.parseDateTime("01/09/1995");
        endDate = formatter.parseDateTime("30/11/2018");

        Period period = new Period(startDate, endDate);

        Log.e("No Of Years : ", period.getYears() + " Years, ");
        Log.e("No Of Months : ", period.getMonths() + " Months, ");
        Log.e("No Of Days : ", period.getDays() + " Days, ");

        tvResult.setText(String.format("No Of Years : %d Years, \nNo Of Months : %d Months, \nNo Of Days : %d Days, ", period.getYears(), period.getMonths(), period.getDays()));

    } catch (Exception e) {
        e.printStackTrace();
    }


}

Ожидаемый вывод кода выше ( проверено на этом сайте и с помощью одного приложения в магазине Google Play)

23 years, 2 months, 29 days

но я получаю ниже результат, используя ту же дату

/goku.com.demo E/No Of Years :: 23 Years, 
/goku.com.demo E/No Of Months :: 2 Months, 
/goku.com.demo E/No Of Days :: 1 Days, 

Может ли кто-нибудь помочь мне найти проблему, что я 'm отсутствует в приведенном выше коде

Я использую использование ниже joda-time Зависимость.

implementation 'joda-time:joda-time:2.9.9'

PS уже проверено ниже ссылки

Если вам нужна дополнительная информация, пожалуйста, дайте мне знать.Заранее спасибо.Ваши усилия будут оценены.

Ответы [ 3 ]

0 голосов
/ 30 ноября 2018

С Java 8 time API было бы легко достичь результата, используя DateTimeFormatter и LocalDate .

import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
....

    public void test() {
        DateTimeFormatter formatter = 
        DateTimeFormatter.ofPattern("dd/MM/yyyy").withLocale(Locale.US);
        LocalDate startDate = LocalDate.parse("01/09/1995", formatter);
        LocalDate endDate = LocalDate.parse("30/11/2018", formatter);

        Period period = Period.between(startDate, endDate);
        System.out.println(String.format("No Of Years : %d Years, \nNo Of Months : %d Months, \nNo Of Days : %d Days, ",
                period.getYears(), period.getMonths(), period.getDays())
        );
    }

Результатнапечатано:

No Of Years : 23 Years, 
No Of Months : 2 Months, 
No Of Days : 29 Days, 
0 голосов
/ 30 ноября 2018

Причина, по которой ваш код Joda Time не работает, заключается в том, что если вы не предоставите объект PeriodType, тогда используется стандартный PeriodType.Стандартный период определяет не только годы, месяцы и дни, которые будут включены в расчет периода, но также и недели.И вы не отображаете количество недель, которое составляет 4 в вашем случае.Если вы напишите period.getWeeks(), он вернет 4.

Чтобы заставить его работать, вы должны предоставить PeriodType в качестве третьего аргумента конструктору Period.Если вы измените объявление period на

Period period = new Period(startDate, endDate, PeriodType.yearMonthDay());

, оно будет работать.Тогда для расчета периода будут использоваться только поля года, месяца и дня.

Но

... лучше перейти на новый API даты и времени Java, доступный в java.time пакет, если вы используете Java 8 или выше.Не поймите меня неправильно, Joda Time - очень хороший API для дат и времени.API даты и времени Java 8 сильно зависит от Joda Time из-за его качества.Его ведущий разработчик на самом деле тот же человек, Стивен Коулборн .

Но Joda Time сейчас находится в режиме обслуживания, и на его веб-сайте пользователям предлагается перейти на java.time (JSR-310).) - основная часть JDK, которая заменяет этот проект.

Использование Java 8 Date and Time API

DateTimeFormatter f = DateTimeFormatter.ofPattern("dd/MM/yyyy").withLocale(Locale.US);

// expected output 23...2....29
LocalDate startDate = LocalDate.parse("01/09/1995", f);
LocalDate endDate = LocalDate.parse("30/11/2018", f);
Period period = Period.between(startDate, endDate);

Backport на Java 6 и 7;Поддержка Android

Большая часть функциональности java.time перенесена на Java 6 и Java 7 в проекте ThreeTen-Backport , также возглавляемом Стивеном Коулборном.Далее адаптирован для более ранних уровней Android API (ниже 26 ) в проекте ThreeTenABP .См. Как использовать ThreeTenABP .

Обратите внимание, что есть некоторые различия между Joda Time и Java Date and Time API.В частности, класс Period из Java Date and Time API менее полон.Однако класс Period из Java Date and Time API обеспечивает функциональность, соответствующую вашим требованиям.


Я вижу, что этот код, использующий java.time, фактически совпадает с кодом @ MaxXFrenzY,Это не из-за копирования-вставки, а из-за того, что новый Java Date and Time API разработан как однозначный и простой.

0 голосов
/ 30 ноября 2018

Вы можете сделать это без Joda-Time. Для типов можно использовать неправильные миллисекунды, но это будет выглядеть так

     SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", 
     Locale.getDefault());
     final Date startdate = format.parse("2018-10-20 23:34:32");
     final Date enddate = format.parse("2019-09-19 23:34:32");
     long n = enddate.getTime() - startdate.getTime();
                    if (n>0) {
                        long year, month, day, hour, minute, second;
                        // year = 365 days
                        year = (n/31536000000);
                        if (year != 0)
                            n = n - (year * 31536000000);
                        // month = 30 Days
                        month = (n/2592000000);
                        if (month != 0)
                            n = n - (month * 2592000000);
                        day = (n / 86400000);
                        if (day != 0)
                            n = n - (day * 86400000);
                        hour = (n / 3600000);
                        if (hour != 0)
                            n = n - (hour * 3600000);
                        minute = (n / 60000);
                        if (minute != 0)
                            n = n - (minute * 60000);
                        second = (n / 1000);
                     }
...