Joda Time和Java8时间差



我正在寻找一个解决方案,以计算两个日期之间的月份。我认为Joda或Java8时间可以做到。但是,当我比较它们时,我发现了一些非常奇怪的东西。

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import org.joda.time.Months;
public class DateMain {
    public static void main(String[] args) throws ParseException {
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    Date d1 = simpleDateFormat.parse("2017-01-28 00:00:00.000");
    Date d2 = simpleDateFormat.parse("2017-02-28 00:00:00.000");
    System.out.println("Test Cast 1");
    System.out.println("joda time api result: " + monthsBetweenJoda(d1, d2) + " month");
    System.out.println("java8 time api result: " + monthsBetweenJava8(d1, d2) + " month");
    Date dd1 = simpleDateFormat.parse("2017-01-29 00:00:00.000");
    Date dd2 = simpleDateFormat.parse("2017-02-28 00:00:00.000");
    System.out.println("Test Cast 2");
    System.out.println("joda time api result: " + monthsBetweenJoda(dd1, dd2) + " month");
    System.out.println("java8 time api result: " + monthsBetweenJava8(dd1, dd2) + " month");
}
public static int monthsBetweenJoda(Date fromDate, Date toDate) {
    if (fromDate == null || toDate == null) {
        throw new IllegalArgumentException();
    }
    org.joda.time.LocalDateTime fromLocalDateTime = org.joda.time.LocalDateTime
        .fromDateFields(fromDate);
    org.joda.time.LocalDateTime toLocalDateTime = org.joda.time.LocalDateTime
        .fromDateFields(toDate);
    Months months = Months.monthsBetween(fromLocalDateTime, toLocalDateTime);
    return months.getMonths();
}
public static long monthsBetweenJava8(Date fromDate, Date toDate) {
    if (fromDate == null || toDate == null) {
        throw new IllegalArgumentException();
    }
    LocalDateTime ldt1 = fromDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    LocalDateTime ldt2 = toDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    return ChronoUnit.MONTHS.between(ldt1, ldt2);
}
}

输出如下:

Test Cast 1
joda time api result: 1 month
java8 time api result: 1 month
Test Cast 2
joda time api result: 1 month
java8 time api result: 0 month

我对测试案例2感到非常困惑,哪个是合理的?

对不起,这是我在这里的第一个问题。已完成的代码。

joda time和java 8 java.time.*具有不同的算法,用于确定之间的月数。

java.time.*只有月份更大(或下个月),只有一个月的声明已经过去。从2017-01-292017-02-28,很明显,第二天(28)少于第一个(29),因此尚未完成一个月。

Joda Time声明一个月已经过去了,因为将1个月添加到2017-01-29将产生2017-02-28

两者都是合理的算法,但我相信java.time.*算法与人们的期望更具一致性(这就是为什么我在编写java.time.*时选择其他算法)。

相关内容

  • 没有找到相关文章

最新更新