Java 8 计算两个日期之间的月份
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48950145/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java 8 calculate months between two dates
提问by SharpLu
NOTE THIS IS NOT A DUPLICATE OF EITHER OF THE FOLLOWING
请注意,这不是以下任何一项的重复
- Calculating the difference between two Java date instances
- calculate months between two dates in java [duplicate]
I have two dates:
我有两个日期:
- Start date:
"2016-08-31"
- End date:
"2016-11-30"
- 开始日期:
"2016-08-31"
- 结束日期:
"2016-11-30"
Its 91 days duration between the above two dates, I expected my code to return 3 months duration, but the below methods only returned 2 months. Does anyone have a better suggestion? Or do you guys think this is a bug in Java 8? 91 days the duration only return 2 months.
上述两个日期之间的持续时间为 91 天,我希望我的代码返回 3 个月的持续时间,但以下方法仅返回 2 个月。有人有更好的建议吗?或者你们认为这是 Java 8 中的一个错误?91天工期只返回2个月。
Thank you very much for the help.
非常感谢你的帮助。
Method 1:
方法一:
Period diff = Period.between(LocalDate.parse("2016-08-31"),
LocalDate.parse("2016-11-30"));
Method 2:
方法二:
long daysBetween = ChronoUnit.MONTHS.between(LocalDate.parse("2016-08-31"),
LocalDate.parse("2016-11-30"));
Method 3:
方法三:
I tried to use Joda library instead of Java 8 APIs, it works. it loos will return 3, It looks like Java duration months calculation also used days value. But in my case, i cannot use the Joda at my project. So still looking for other solutions.
我尝试使用 Joda 库而不是 Java 8 API,它可以工作。它会返回 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);
采纳答案by AxelH
Since you don't care about the days in your case. You only want the number of month between two dates, use the documentation of the period to adapt the dates, it used the days as explain by Jacob
. Simply set the days of both instance to the same value (the first day of the month)
因为你不在乎你的情况下的日子。您只需要两个日期之间的月份数,使用期间的文档来调整日期,它使用天数作为解释Jacob
。只需将两个实例的天数设置为相同的值(每月的第一天)
Period diff = Period.between(
LocalDate.parse("2016-08-31").withDayOfMonth(1),
LocalDate.parse("2016-11-30").withDayOfMonth(1));
System.out.println(diff); //P3M
Same with the other solution :
与其他解决方案相同:
long monthsBetween = ChronoUnit.MONTHS.between(
LocalDate.parse("2016-08-31").withDayOfMonth(1),
LocalDate.parse("2016-11-30").withDayOfMonth(1));
System.out.println(monthsBetween); //3
Edit from @Olivier Grégtheitroadecomment:
从@Olivier Grégtheitroade评论编辑:
Instead of using a LocalDate
and set the day to the first of the month, we can use YearMonth
that doesn't use the unit of days.
除了使用 aLocalDate
并将日期设置为每月的第一天,我们可以使用YearMonth
不使用天数单位的 。
long monthsBetween = ChronoUnit.MONTHS.between(
YearMonth.from(LocalDate.parse("2016-08-31")),
YearMonth.from(LocalDate.parse("2016-11-30"))
)
System.out.println(monthsBetween); //3
回答by Jacob G.
The documentation of Period#betweenstates the following:
Period#between的文档说明如下:
The start date is included, but the end date is not.
包括开始日期,但不包括结束日期。
Furthermore:
此外:
A month is considered if the end day-of-month is greater than or equal to the start day-of-month.
如果月的结束日大于或等于月的开始日,则认为是一个月。
Your end day-of-month 30
is notgreater than or equal to your start day-of-month 31
, so a third month is not considered.
您的最终日的一个月30
是不大于或等于你的起始日期的日31
,因此第三个月不考虑。
Note the parameter names:
注意参数名称:
public static Period between?(LocalDate startDateInclusive, LocalDate endDateExclusive)
To return 3 months, you can increment the endDateExclusive
by a single day.
要返回 3 个月,您可以将 增加endDateExclusive
一天。
回答by SharpLu
After the short investigation, still not totally fix my question, But I used a dirty solution to avoid return the incorrect duration. At least, we can get the reasonable duration months.
经过短暂的调查,仍然没有完全解决我的问题,但我使用了一个肮脏的解决方案来避免返回不正确的持续时间。至少,我们可以得到合理的持续时间月份。
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);
}
回答by abhi
In case you want stick to java.time.Period
API
如果您想坚持使用java.time.Period
API
As per java.time.Period
documentation
根据java.time.Period
文档
Period between(LocalDate startDateInclusive, LocalDate endDateExclusive)
where
在哪里
@param startDateInclusive the start date, inclusive, not null
@param endDateExclusive the end date, exclusive, not null
So it is better to adjust your implementation to make your end date inclusive and get your desired result
因此,最好调整您的实施,使您的结束日期包含在内并获得您想要的结果
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
回答by Yandi Ongkojoyo
//Backward compatible with older Java
//向后兼容旧的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);
}
回答by Anas
You have to be careful, never use LocalDateTime to calculate months between two dates the result is weird and incorrect, always use LocalDate !
您必须小心,切勿使用 LocalDateTime 计算两个日期之间的月份,结果很奇怪且不正确,请始终使用 LocalDate !
here's is some code to prove the above:
这是一些代码来证明上述内容:
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
}
}
My 2%
我的 2%
回答by Zon
Since Java8:
从 Java8 开始:
ChronoUnit.MONTHS.between(startDate, endDate);