Java日期月差异

42 java date

我有开始日期和结束日期.

我需要Java中这两个日期之间的月数.

例如

  • 从日期:2009-01-29
  • 迄今为止:2009-02-02

它有一个日期和一个2月日期.

它应该返回2.

Ste*_*sop 41

正如其他人所说的那样,如果有一个库会在几个月内给你时差,你可以使用它,那么你也可以.

否则,如果y1m1是第一个日期的年份和月份,y2并且m2是第二个日期的年份和月份,那么您想要的值是:

(y2 - y1) * 12 + (m2 - m1) + 1;
Run Code Online (Sandbox Code Playgroud)

请注意,即使第二个日期在第一个日期之后,中间项(m2-m1)也可能是负数,但这很好.

无论是月份是1月= 0还是1月= 1都无关紧要,只要这两个日期使用相同的基础,无论是年份是AD,自1900年以来的年份,还是其他什么都无关紧要.因此,例如,不要混合AD和BC日期,因为没有第0年,因此BC从AD偏移1.

y1如果以合适的形式提供给您,或者使用日历,您可以直接从日期获得等.


Rol*_*epp 36

除了使用Joda时间,这似乎是我最喜欢的建议,我提供以下代码段:

public static final int getMonthsDifference(Date date1, Date date2) {
    int m1 = date1.getYear() * 12 + date1.getMonth();
    int m2 = date2.getYear() * 12 + date2.getMonth();
    return m2 - m1 + 1;
}
Run Code Online (Sandbox Code Playgroud)

编辑:自Java 8以来,有一种更标准的计算相同差异的方法.请参阅使用JSR-310 api的替代答案.

  • 你的意思是[Joda-Time](http://www.joda.org/joda-time/)?[Yoda](https://en.wikipedia.org/wiki/Yoda)时间很久以前在一个遥远的星系中. (10认同)
  • 此外,如果您正确阅读OP问题,这正是所要求的. (2认同)

Bri*_*new 30

强烈推荐Joda-Time.

  1. 它使这种工作变得非常容易(查看期间)
  2. 它不会受到困扰当前日期/时间对象的线程问题的影响(我正在考虑格式化程序,尤其是格式化程序)
  3. 它是Java 7附带的新Java日期/时间API的基础(因此您正在学习将成为标准的东西)

另请注意尼克霍尔特的评论.夏令时变化.

  • 如果你可以使用Joda任何日期相关的代码.我添加了第4号.Joda知道多年来日期时间标准发生的各种变化,其计算考虑在内(特别是在多年来一直困扰夏令时的欧洲). (5认同)
  • 实际上,新的[JSR 310:日期和时间API](http://jcp.org/en/jsr/detail?id=310)将在2014年推出Java 8(不是上面提到的Java 7).Java 8现在正在预览版中. (3认同)

Rol*_*epp 19

既然JSR-310已经包含在Java 8及更高版本的SDK中,这里有一个更标准的方法来获得两个日期值的差异:

public static final long getMonthsDifference(Date date1, Date date2) {
    YearMonth m1 = YearMonth.from(date1.toInstant().atZone(ZoneOffset.UTC));
    YearMonth m2 = YearMonth.from(date2.toInstant().atZone(ZoneOffset.UTC));

    return m1.until(m2, ChronoUnit.MONTHS) + 1;
}
Run Code Online (Sandbox Code Playgroud)

这有利于清楚地说明计算的精确度,并且很容易理解计算的目的是什么.


Kuc*_*chi 16

Java 8解决方案:

@Test
public void monthBetween() {

    LocalDate d1 = LocalDate.of(2013, Month.APRIL, 1);
    LocalDate d2 = LocalDate.of(2014, Month.APRIL, 1);

    long monthBetween = ChronoUnit.MONTHS.between(d1, d2);

    assertEquals(12, monthBetween);

}
Run Code Online (Sandbox Code Playgroud)


nig*_*2k1 8

使用joda时间就是这样(我比较了今天和2012年12月20日之间的几个月)

import org.joda.time.DateTime ;
import org.joda.time.Months;

DateTime x = new DateTime().withDate(2009,12,20); // doomsday lol

Months d = Months.monthsBetween( new DateTime(), x);
int monthsDiff = d.getMonths();
Run Code Online (Sandbox Code Playgroud)

结果:41个月(2009年7月6日起)

应该容易吗?:)

ps:你也可以使用SimpleDateFormat转换日期,如:

Date x = new SimpleDateFormat("dd/mm/yyyy").parse("20/12/2009");
DateTime z = new DateTime(x);
Run Code Online (Sandbox Code Playgroud)

如果您不想使用Joda(无论出于何种原因),您可以将日期转换为TimeStamp,然后在两个日期之间进行毫秒的差异,然后计算回数月.但我还是喜欢用Joda时间来简化:)


Unc*_*roh 8

根据上面建议的答案,我自己编写了一些,我将其添加到现有的DateUtils类中:

    public static Integer differenceInMonths(Date beginningDate, Date endingDate) {
        if (beginningDate == null || endingDate == null) {
            return 0;
        }
        Calendar cal1 = new GregorianCalendar();
        cal1.setTime(beginningDate);
        Calendar cal2 = new GregorianCalendar();
        cal2.setTime(endingDate);
        return differenceInMonths(cal1, cal2);
    }

    private static Integer differenceInMonths(Calendar beginningDate, Calendar endingDate) {
        if (beginningDate == null || endingDate == null) {
            return 0;
        }
        int m1 = beginningDate.get(Calendar.YEAR) * 12 + beginningDate.get(Calendar.MONTH);
        int m2 = endingDate.get(Calendar.YEAR) * 12 + endingDate.get(Calendar.MONTH);
        return m2 - m1;
    }
Run Code Online (Sandbox Code Playgroud)

关联单元测试:

    public void testDifferenceInMonths() throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        assertEquals(12, DateUtils.differenceInMonths(sdf.parse("2014/03/22"), sdf.parse("2015/03/22")).intValue());

        assertEquals(11, DateUtils.differenceInMonths(sdf.parse("2014/01/01"), sdf.parse("2014/12/25")).intValue());

        assertEquals(88, DateUtils.differenceInMonths(sdf.parse("2014/03/22"), sdf.parse("2021/07/05")).intValue());

        assertEquals(6, DateUtils.differenceInMonths(sdf.parse("2014/01/22"), sdf.parse("2014/07/22")).intValue());
    }
Run Code Online (Sandbox Code Playgroud)


kgi*_*kis 2

为此,您可以使用 Calendar 或Joda 时间库。

在 Joda 时间中,您可以使用 Days.daysBetween() 方法。然后您可以计算月份差异。您还可以使用 DateTime.getMonthOfYear() 并进行减法(对于同一年的日期)。

  • 使用 Months.monthsBetween 比转换为 Days 然后回滚到 Months 更好;) (3认同)