【问题标题】:How to calculate No of Years, Months and days between two dates using Joda-Time如何使用 Joda-Time 计算两个日期之间的年数、月数和天数
【发布时间】:2019-05-02 07:44:26
【问题描述】:

我使用下面的代码使用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 store 中使用一个应用程序)

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.已经在下面的链接中检查过

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

【问题讨论】:

  • 您是否尝试将PeriodType.yearMonthDay() 作为第三个参数提供给Period 构造函数?
  • @MCEmperor 没有你能解释更多关于PeriodType.yearMonthDay()的信息,因为我是joda-time的新手,感谢您的回复
  • 您是否考虑过从 java.time 包迁移到新的 Java 日期和时间 API?
  • @MCEmperor 如果您有任何使用Java Date and Time API 的解决方案,请随时回复
  • 仅供参考,Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。见Tutorial by Oracle

标签: java android jodatime android-jodatime


【解决方案1】:

您的 Joda 时间代码不起作用的原因是,如果您不提供 PeriodType 对象,则使用标准 PeriodType。 standard period 类型不仅定义了要包含在 Period 计算中的年、月和日,还定义了周。而且您没有显示周数,在您的情况下为 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 的影响很大,因为它的质量。它的首席开发者实际上是同一个人,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);

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

java.time 的大部分功能都在 ThreeTen-Backport 项目中向后移植到 Java 6 和 Java 7,该项目也由 Stephen Colebourne 领导。进一步适用于ThreeTenABP 项目中的早期Android API 级别(低于26)。见How to use ThreeTenABP

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


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

【讨论】:

  • 请使用yearMonthDay() 而不是yearMonthDayTime(),这样可以更好地考虑到OP 对时间部分不感兴趣的事实。并且记录在案:java.time.Period 之所以有效,是因为它意外地支持 OP 想要的内容,但与 Joda-Time 相比,它提供了非常有限的时期类型选择(只有一种)。
  • @MenoHochschild 我已经更新了代码。我正在寻找有关 Joda Time 和then I found this 的更多信息——没错,你自己的帖子。 ;-) 我会将其包含在答案中。
【解决方案2】:

使用Java 8 time 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())
        );
    }

打印的结果是:

No Of Years : 23 Years, 
No Of Months : 2 Months, 
No Of Days : 29 Days, 

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2011-04-17
      • 1970-01-01
      • 2022-01-19
      • 2021-07-08
      • 1970-01-01
      • 1970-01-01
      • 2014-03-07
      • 1970-01-01
      • 2014-10-01
      相关资源
      最近更新 更多