如何使用 Joda-Time 计算两个日期之间的年数、月数和天数

How to calculate No of Years, Months and days between two dates using Joda-Time

我使用下面的代码使用 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();
    }


}

以上代码的预期输出是(checked using this site 并在 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, 

谁能帮我找出上面代码中遗漏的问题

I'm using using below joda-time Dependency.

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

P.S. 已检查以下链接

如果需要更多信息,请告诉我。提前致谢。您的努力将不胜感激。

你可以在没有 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);
                     }

Java 8 time API it would be easy to achieve the result using DateTimeFormatter and 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, 

您的 Joda 时间代码不起作用的原因是,如果您不提供 PeriodType 对象,则会使用标准 PeriodType。 standard 期间类型不仅定义了要包含在期间计算中的年、月和日,还定义了周。而且您没有显示周数,在您的情况下为 4。如果你写 period.getWeeks() 它将 return 4.

为了使其工作,您必须提供 PeriodType 作为 Period 构造函数的第三个参数。如果将 period 的声明更改为

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

那就行了。期间计算将仅使用年、月和日字段。

但是

...最好迁移到 java.time package, if you are using Java 8 or above. Don't get me wrong, Joda Time is a very good date and time API. Java 8's date and time API is heavily influenced on Joda Time, because of its quality. Its lead developer is actually the same person, Stephen Colebourne.

中可用的新 Java 日期和时间 API

但是 Joda Time 现在处于维护模式,在其网站上要求用户迁移到 java.time (JSR-310) - JDK 的核心部分,它取代了这个项目。

使用 Java 8 日期和时间 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);

向后移植到 Java 6 和 7; Android支持

大多数 java.time 功能已向后移植到 ThreeTen-Backport project, also led by Stephen Colebourne. Further adapted for earlier Android API levels (below 26) in the ThreeTenABP project. See .

中的 Java 6 和 Java 7

请注意,Joda 时间与 Java 日期和时间 API 之间有 some differences。特别是,Java 日期和时间 API 中的 Period class 不太全面。但是,Java 日期和时间 API 中的 Period class 提供了满足您要求的功能。


我看到这段使用 java.time 的代码实际上与@MaxXFrenzY 的相同。这不是因为复制粘贴,而是因为新的 Java 日期和时间 API 被设计为既明确又直接。