请注意,这不是以下任何一项重复
我有两个日期:
"2016-08-31"
"2016-11-30"
在上述两个日期之间有91天的持续时间,我预计我的代码将返回3个月的持续时间,但以下方法仅返回2个月。有人有更好的建议吗?或者你们认为这是Java 8中的一个错误吗? 91天,持续时间仅返回2个月。
非常感谢您的帮助。
方法1:
Period diff = Period.between(LocalDate.parse("2016-08-31"),
LocalDate.parse("2016-11-30"));
方法2:
long daysBetween = ChronoUnit.MONTHS.between(LocalDate.parse("2016-08-31"),
LocalDate.parse("2016-11-30"));
方法3:
我尝试使用Joda库而不是Java 8 API,它可以工作。它将loos返回3,看起来像Java持续时间的月计算也使用了天数值。但就我而言,我不能在我的项目中使用Joda。所以还在寻找其他解决方案。
LocalDate dateBefore= LocalDate.parse("2016-08-31");
LocalDate dateAfter = LocalDate.parse("2016-11-30");
int months = Months.monthsBetween(dateBefore, dateAfter).getMonths();
System.out.println(months);
答案 0 :(得分:9)
因为你不关心你案件的日子。您只需要两个日期之间的月份数,使用期间的文档来调整日期,它使用日期作为Jacob
的解释。只需将两个实例的天数设置为相同的值(该月的第一天)
Period diff = Period.between(
LocalDate.parse("2016-08-31").withDayOfMonth(1),
LocalDate.parse("2016-11-30").withDayOfMonth(1));
System.out.println(diff); //P3M
与其他解决方案相同:
long monthsBetween = ChronoUnit.MONTHS.between(
LocalDate.parse("2016-08-31").withDayOfMonth(1),
LocalDate.parse("2016-11-30").withDayOfMonth(1));
System.out.println(monthsBetween); //3
答案 1 :(得分:3)
Period#between的文档说明如下:
包含开始日期,但结束日期不包括在内。
此外:
如果结束日期大于或等于月初日,则会考虑一个月。
您的结束日期30
不大于或等于您的开始日期31
,因此不会考虑第三个月。
请注意参数名称:
public static Period between(LocalDate startDateInclusive, LocalDate endDateExclusive)
要返回3个月,您可以将endDateExclusive
增加一天。
答案 2 :(得分:2)
如果您想坚持使用java.time.Period
API
根据java.time.Period
文档
Period between(LocalDate startDateInclusive, LocalDate endDateExclusive)
其中
@param startDateInclusive the start date, inclusive, not null
@param endDateExclusive the end date, exclusive, not null
因此,最好调整实施方式,使结束日期具有包容性,并获得所需的结果
Period diff = Period.between(LocalDate.parse("2016-08-31"),
LocalDate.parse("2016-11-30").plusDays(1));
System.out.println("Months : " + diff.getMonths());
//Output -> Months : 3
答案 3 :(得分:1)
///与旧版Java向后兼容
public static int monthsBetween(Date d1, Date d2){
if(d2==null || d1==null){
return -1;//Error
}
Calendar m_calendar=Calendar.getInstance()
m_calendar.setTime(d1);
int nMonth1=12*m_calendar.get(Calendar.YEAR)+m_calendar.get(Calendar.MONTH);
m_calendar.setTime(d2);
int nMonth2=12*m_calendar.get(Calendar.YEAR)+m_calendar.get(Calendar.MONTH);
return java.lang.Math.abs(nMonth2-nMonth1);
}
答案 4 :(得分:1)
您必须小心,永远不要使用LocalDateTime来计算两个日期之间的月份,结果是奇怪的和不正确的,请始终使用LocalDate!
这是一些证明以上内容的代码:
package stack.time;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
public class TestMonthsDateTime {
public static void main(String[] args) {
/**------------------Date Time----------------------------*/
LocalDateTime t1 = LocalDateTime.now();
LocalDateTime t2 = LocalDateTime.now().minusMonths(3);
long dateTimeDiff = ChronoUnit.MONTHS.between(t2, t1);
System.out.println("diff dateTime : " + dateTimeDiff); //diff dateTime : 2
/**-------------------------Date----------------------------*/
LocalDate t3 = LocalDate.now();
LocalDate t4 = LocalDate.now().minusMonths(3);
long dateDiff = ChronoUnit.MONTHS.between(t4, t3);
System.out.println("diff date : " + dateDiff);//diff date : 3
}
}
我的2%
答案 5 :(得分:0)
经过短暂的调查,仍然没有完全解决我的问题,但我使用了一个肮脏的解决方案,以避免返回不正确的持续时间。至少,我们可以获得合理的持续时间。
private static long durationMonths(LocalDate dateBefore, LocalDate dateAfter) {
System.out.println(dateBefore+" "+dateAfter);
if (dateBefore.getDayOfMonth() > 28) {
dateBefore = dateBefore.minusDays(5);
} else if (dateAfter.getDayOfMonth() > 28) {
dateAfter = dateAfter.minusDays(5);
}
return ChronoUnit.MONTHS.between(dateBefore, dateAfter);
}
答案 6 :(得分:0)
从Java8开始:
ChronoUnit.MONTHS.between(startDate, endDate);
答案 7 :(得分:0)
此示例检查第二个日期是否是该月的月底。如果是该月的月底,并且该月的第一个日期大于第二个月的日期,则它会知道需要添加 1
LocalDate date1 = LocalDate.parse("2016-08-31");
LocalDate date2 = LocalDate.parse("2016-11-30");
long monthsBetween = ChronoUnit.MONTHS.between(
date1,
date2);
if (date1.isBefore(date2)
&& date2.getDayOfMonth() == date2.lengthOfMonth()
&& date1.getDayOfMonth() > date2.getDayOfMonth()) {
monthsBetween += 1;
}