Подтвердить что ты не робот

Время Джоды и 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, и какой из них разумный?

Извините, это мой первый вопрос здесь. Завершенный код.

4b9b3361

Ответ 1

Joda-Time и Java 8 java.time.* имеют разные алгоритмы для определения количества месяцев между ними.

java.time.* объявляет только месяц, прошедший после того, как день месяца больше (или в следующем месяце). От 2017-01-29 до 2017-02-28 ясно, что второй день месяца (28) меньше первого (29), поэтому месяц еще не завершен.

Joda-Time объявляет, что месяц прошел, потому что добавление 1 месяца к 2017-01-29 приведет к 2017-02-28.

Оба являются правдоподобными алгоритмами, но я считаю, что алгоритм java.time.* будет более точно соответствовать ожиданиям людей (именно поэтому я выбрал другой алгоритм при написании java.time.*).