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

Gok*_*oku 2 java android jodatime android-jodatime

我使用下面的代码来计算两个日期之间的年数、月数和天数 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();
    }


}
Run Code Online (Sandbox Code Playgroud)

上面代码的预期输出是(使用本网站并使用谷歌播放商店中的一个应用程序检查

23 years, 2 months, 29 days
Run Code Online (Sandbox Code Playgroud)

但我使用相同的日期得到低于结果

/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, 
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮助我找到上面代码中缺少的问题

我正在使用下面的joda-time依赖项。

implementation 'joda-time:joda-time:2.9.9'
Run Code Online (Sandbox Code Playgroud)

PS已经检查以下链接

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

MC *_*ror 6

您的 Joda 时间代码不起作用的原因是,如果您不提供PeriodType对象,则使用标准 PeriodType。该标准期间类型定义不仅年,月,日,以被列入周期计算,而且周。而且您没有显示周数,在您的情况下为 4。如果你写period.getWeeks()它会返回4

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

Period period = new Period(startDate, endDate, PeriodType.yearMonthDay());
Run Code Online (Sandbox Code Playgroud)

然后它会工作。期间计算将仅使用年、月和日字段。

...java.time如果您使用的是 Java 8 或更高版本,最好迁移到包中提供的新 Java 日期和时间 API 。不要误会我的意思,Joda Time 是一个非常好的日期和时间 API。Java 8 的日期和时间 API 受 Joda Time 的影响很大,因为它的质量。它的首席开发人员实际上是同一个人,Stephen Colebourne

但是 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);
Run Code Online (Sandbox Code Playgroud)

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

java.time 在同样由 ​​Stephen Colebourne 领导的ThreeTen-Backport项目中,大部分功能都向后移植到 Java 6 和 Java 7 。进一步适应了ThreeTenABP项目中早期的 Android API 级别(低于26)。查看如何使用 ThreeTenABP

请注意,Joda Time 和 Java Date and Time API 之间存在一些差异。特别是,PeriodJava Date and Time API 中的类不太全面。但是,PeriodJava 日期和时间 API 中的类提供了满足您要求的功能。


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


小智 5

使用Java 8 时间API 可以很容易地使用DateTimeFormatterLocalDate实现结果。

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())
        );
    }
Run Code Online (Sandbox Code Playgroud)

打印出来的结果是:

No Of Years : 23 Years, 
No Of Months : 2 Months, 
No Of Days : 29 Days, 
Run Code Online (Sandbox Code Playgroud)