我要找出不是。两个日期之间的月份,包括首尾两个月。我正在使用ChronoUnit.Months.between,但得到了意想不到的结果。
代码适用范围:1月31日-7月31日
失败时间:1月31 -6月30日
失败的代码:
import java.time.LocalDate;
import static java.time.temporal.ChronoUnit.MONTHS;
public class HelloWorld{
public static void main(String []args){
LocalDate startDate=LocalDate.of(2018,01,31);
LocalDate endDate=LocalDate.of(2018,6,30);
//Both dates inclusive, hence adding 1
long noOfMonths = (MONTHS.between(startDate,endDate)) + 1L;
System.out.println(" ********* No. of months between the two dates : " + noOfMonths);
}
}
预期:6(1,2,3,4,5,6)实际:5
有效的代码:
import java.time.LocalDate;
import static java.time.temporal.ChronoUnit.MONTHS;
public class HelloWorld{
public static void main(String []args){
LocalDate startDate=LocalDate.of(2018,01,31);
LocalDate endDate=LocalDate.of(2018,7,31);
//Both dates inclusive, hence adding 1
long noOfMonths = (MONTHS.between(startDate,endDate)) + 1L;
System.out.println(" ********* No. of months between the two dates : " + noOfMonths);
}
}
预期:7(1,2,3,4,5,6,7)实际:7
你看到同样的行为了吗?有没有什么替代的方法呢?
谢谢
发布于 2018-06-17 14:40:45
半开
另外两个答案by davidxxx和by Ole V.V.都是正确且信息丰富的。
我想补充一下在日期-时间工作中常用的另一种定义时间跨度的方法:半开放。在半开放方法中,开始是包容性的,而结尾是排他性的。因此,今年上半年的月份( 1月、2月、3月、4月和6月)被跟踪为从1月1日开始,一直到(但不包括)7月1日。
有时我们会在日常生活中直观地使用这种方法。例如,如果一个教室的孩子们从中午12点到下午1点休息吃午饭,那么学生们应该在下午1点的钟声敲响之前回到座位上。午休时间持续到下午1点,但不包括下午1点
我相信您会发现,始终如一地使用Half-Open方法会使您的代码更易于阅读、调试和维护。
现代的java.time类使用这种方法来定义时间跨度。
LocalDateRange
Ole V.V.的回答明智地建议您使用YearMonth
类来帮助您的工作。
另一个有用的类来自项目:org.threeten.extra.LocalDateRange
。您可以在单个对象中表示整个日期范围。
您可以使用开始日期和六个月的Period
实例化。
LocalDateRange ldr = LocalDateRange.of(
LocalDate.of( 2018 , Month.JANUARY , 1 ) ,
Period.ofMonths( 6 )
) ;
或者指定开始日期和停止日期。
LocalDateRange ldr = LocalDateRange.of(
LocalDate.of( 2018 , Month.JANUARY , 1 ) ,
LocalDate.of( 2018 , Month.JULY , 1 ) // Half-open.
) ;
虽然我不推荐这样做,但如果您坚持使用完全封闭的方法,即开始和结束都包含在内,那么LocalDateRange
确实提供了LocalDateRange.ofClosed()
。
LocalDateRange ldr = LocalDateRange.ofClosed( // `ofClosed` vs `of`.
LocalDate.of( 2018 , Month.JANUARY , 1 ) ,
YearMonth( 2018 , Month.JUNE ).atEndOfMonth() // Fully-closed.
) ;
您可以通过Period
类从LocalDateRange
获取月数。
LocalDateRange ldr = LocalDateRange.of(
LocalDate.of( 2018 , Month.JANUARY , 1 ) ,
Period.ofMonths( 6 )
) ;
Period p = ldr.toPeriod() ;
long totalMonths = p.toTotalMonths() ; // 6
关于java.time
框架内置于Java8和更高版本中。这些类取代了麻烦的旧legacy日期时间类,如java.util.Date
、Calendar
和SimpleDateFormat
。
现在在maintenance mode中的项目建议迁移到java.time类。
要了解更多信息,请参阅。和搜索堆栈溢出,以获得许多示例和解释。规范为JSR 310。
您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC driver。不需要字符串,也不需要java.sql.*
类。
从哪里获取java.time类?
内置
中的
项目使用额外的类扩展了java.time。这个项目是未来可能添加到java.time中的试验场。您可能会在这里找到一些有用的类,如Interval
、YearWeek
、YearQuarter
和more。
发布于 2022-03-02 16:01:14
其他解决方案:
int getInclusiveMonthsDiff(LocalDate startDate, LocalDate endDate) {
return (endDate.monthValue + endDate.year * 12) - (startDate.monthValue + startDate.year * 12) + 1
}
https://stackoverflow.com/questions/50890562
复制相似问题