如何使用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();
}

}

上述代码的预期输出是(使用此网站和谷歌播放商店中的一个应用程序进行检查(

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, 

有人能帮我找到问题吗?我在上面的代码中缺少什么

我使用以下joda-time依赖项。

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

p.S.已在链接下方检查

  • 获取两次约会之间的确切年份、日期或月份
  • 如何计算年份中两个日期之间的差异。。。等与Joda Time

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

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

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

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

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

但是

如果您使用的是Java 8或更高版本,最好迁移到java.time包中提供的新Java日期和时间API。别误会我的意思,Joda Time是一个非常好的日期和时间API。Java 8的日期和时间API由于其质量而受到Joda time的严重影响。它的主要开发者实际上是同一个人,斯蒂芬·科尔伯恩。

但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支持

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

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


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

使用Java 8时间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, 

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

最新更新