简体   繁体   English

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

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

I'm using below code 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();
    }


}

The expected output of above code is( checked using this site and using one app in google play store) 以上代码的预期输出是( 使用此网站并使用Google Play商店中的一个应用程序进行了检查

23 years, 2 months, 29 days

but I'm getting below result using same date 但是我使用相同的日期低于结果

/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, 

Can any one help me to find issue what I'm missing in above code 谁能帮我找到上面代码中所缺少的问题

I'm using using below joda-time Dependency. 我正在使用下面的joda-time依赖。

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

PS already checked below links PS已检查以下链接

If need more information please do let me know. 如果需要更多信息,请告诉我。 Thanks in advance. 提前致谢。 Your efforts will be appreciated. 您的努力将不胜感激。

The reason that your Joda Time code does not work, is because if you don't provide a PeriodType object, then the standard PeriodType is used. 您的Joda时间代码不起作用的原因是,如果不提供PeriodType对象,则使用标准的PeriodType。 The standard period type defines not only years, months and days to be included in the Period calculation, but also weeks. 标准期间类型不仅定义要在“期间”计算中包括的年,月和日,而且还定义周。 And you're not displaying the number of weeks, which is 4 in your case. 而且您没有显示星期数,在您的情况下为4。 If you write period.getWeeks() it'll return 4 . 如果编写period.getWeeks()它将返回4

In order to make it work, you have to provide a PeriodType as third argument to the Period constructor. 为了使其工作,您必须提供PeriodType作为Period构造函数的第三个参数。 If you change the declaration of period to 如果将period声明更改为

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

then it'll work. 这样就可以了 The period calculation will then only use the year, month and day fields. 然后,期间计算将仅使用年,月和日字段。

But

...it is better to migrate to the new Java Date and Time API available in the java.time package, if you are using Java 8 or above. ...如果您使用的是Java 8或更高版本,最好迁移到java.time包中可用的新Java Date and Time API。 Don't get me wrong, Joda Time is a very good date and time API. 别误会,Joda Time是一个非常不错的日期和时间API。 Java 8's date and time API is heavily influenced on Joda Time, because of its quality. Java 8的日期和时间API由于其质量而在Joda Time中受到很大影响。 Its lead developer is actually the same person, Stephen Colebourne . 它的主要开发人员实际上是同一个人Stephen Colebourne

But Joda Time is now in maintenance mode, and on its website users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project. 但是Joda Time现在处于维护模式,并且在其网站上要求用户迁移到java.time(JSR-310),这是替代该项目的JDK的核心部分。

Using Java 8 Date and Time API 使用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);

Backport to Java 6 and 7; 向Java 6和7的反向移植; Android support Android支持

Most of the java.time functionality is back-ported to Java 6 and Java 7 in the ThreeTen-Backport project, also led by Stephen Colebourne. java.time领导的ThreeTen-Backport项目中,大多数java.time功能都被反向移植到Java 6和Java 7。 Further adapted for earlier Android API levels (below 26 ) in the ThreeTenABP project. ThreeTenABP项目中进一步适应了早期的Android API级别(低于26 )。 See How to use ThreeTenABP . 请参阅如何使用ThreeTenABP

Note that there are some differences between Joda Time and the Java Date and Time API. 请注意,Joda时间与Java日期和时间API之间存在一些差异 In particular, the Period class from the Java Date and Time API is less comprehensive. 特别是,Java日期和时间API中的Period类不太全面。 However, the Period class from the Java Date and Time API provides the functionality which meets your requirement. 但是,Java日期和时间API中的Period类提供了满足您要求的功能。


I see that this code using java.time is actually the same as @MaxXFrenzY's. 我看到使用java.time这段代码实际上与@MaxXFrenzY的相同。 This is not because of copy-paste, that is because the new Java Date and Time API is designed to be both unambiguous and straightforward. 这不是因为复制粘贴,而是因为新的Java日期和时间API的设计既明确又简单。

With Java 8 time API it would be easy to achieve the result using DateTimeFormatter and LocalDate . 使用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())
        );
    }

The result printed is: 打印结果为:

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

You can do this without Joda-Time There can be used wrong milliseconds for types but it will look like this 您可以在没有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);
                     }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM