Я ищу решение для расчета месяцев между двумя датами. Я думаю, что joda или java8 time могут это сделать. Но когда я сравнивал их, я обнаружил кое-что действительно странное.
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, и какой из них разумен?
Извините, это мой первый вопрос. Заполненный код прилагается.
fromDate.plusMonths(x) <= toDate
, что разумно, если добавить 1 месяц к 29 января, все равно будет 28 февраля. В основном календарная арифметика странная. - person Jon Skeet   schedule 15.09.2017java.sql.Date
илиjava.util.Date
? Пожалуйста, задокументируйте этот факт и покажите, как вы генерируете своиDate
объекты, передаваемые в виде пары аргументов. И покажите, как вы сгенерировали выходные строки. Ваш вывод не совпадает с выводом методаtoString
наjava.sql.Date
илиjava.util.Date
. Предоставьте нам MCVE . Ваш код, как показано, не является полным, поэтому мы не можем воспроизвести ваш сценарий. - person Basil Bourque   schedule 15.09.2017LocalDate.of(2017, 1, 29).plusMonths(1L)
приводит кjava.time.LocalDate = 2017-02-28
, но получение месячного интервала между ними приводит к 0. Может быть ошибкой. - person ailveen   schedule 15.09.2017DAYS
,MONTHS
илиYEARS
или почти все из них на самом деле). - person Hulk   schedule 15.09.2017end.time.isBefore(time)
- может быть, это так в вашем тесте (хотя это не похоже на ваш результат)? - person Hulk   schedule 15.09.2017