我正在尝试检查用户选择的日期范围是否在数据库中存在的日期范围内。
例如
用户选择:
开始日期:2022年9月24日
结束日期:2022年9月30日
数据库中的日期范围为:
开始日期:2022年9月28日
结束日期:2022年9月30日
想象一下,你在2009年28日之间预订了一辆车→如果用户想要在24/09之间预订该车;30/09,则应用程序应通知他们该车已在该日期预订,因为它已在28-->30.
我的情况与此类似:检查日期范围是否在日期范围内。只有那个问题是关于C#的,我正在编写Java。
到目前为止我的代码:
boolean isFound = DateHelper.isWithinRange2Dates(
/*ENTERED BY USER*/
string2Date("24/09/2022"),
string2Date("30/09/2022"),
/*IN DATABASE*/
string2Date("28/09/2022"),
string2Date("30/09/2022"));
ToastUtils.showLong(isFound ? "FOUND" : "NOT FOUND");
使用的方法:
public static boolean isWithinRange(Date selectedDate, Date startDate, Date endDate) {
return selectedDate.after(startDate) && (selectedDate.before(endDate) || DateUtils.isSameDay(selectedDate, endDate));
}
public static boolean isWithinRange2Dates(Date selectedStartDate, Date selectedEndDate, Date startDate, Date endDate) {
return isWithinRange(selectedStartDate, startDate, endDate) && isWithinRange(selectedEndDate, startDate, endDate);
}
@SuppressLint("SimpleDateFormat")
public static Date string2Date(String dateStr) {
try {
return new SimpleDateFormat("dd/MM/yyyy").parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
问题:
2009年28日-->30/09在24/09->30/09因此该方法应为真正的
问题:
如何检查所选的开始和结束日期是否在日期范围内?
tl;dr
org.threeten.extra.LocalDateRange.of
(
LocalDate.of( … ) ,
LocalDate.of( … )
)
.encloses
(
LocalDateRange.of
(
startJavaSqlDate.toLocalDate() ,
stopJavaSqlDate.toLocalDate()
)
)
避免使用传统日期时间类
您使用的是糟糕的日期-时间类,这些类在几年前被JSR310中定义的现代java.time类所取代。
Date
类中的许多设计缺陷之一是实际上存在两个Date
类:
java.util.Date
java.sql.Date
第一个表示UTC中看到的时刻。第二个假装只代表一个日期,没有一天中的时间,也没有偏移量或时区。但实际上,在判断极为糟糕的情况下,第二类从第一类扩展而来……因此它确实在内部代表UTC中的一个时刻。凌乱的是的,一团糟。
LocalDate
你在问题中没有提到你在用哪门课。所以我选择第二个,java.sql.Date
。
当收到java.sql.Date
对象时,立即转换为现代替换:LocalDate
。通过调用添加到旧类中的新转换方法来完成此操作。
LocalDate ld = myJavaSqlDate.toLocalDate() ;
LocalDateRange
要比较日期范围,可以自己编写代码。但为什么要麻烦呢?将ThreeTen Extra库添加到您的项目中。这样可以访问LocalDateRange
类。该类提供了几种方便的方法,如contains
、abuts
、encloses
、overlaps
等。
LocalDateRange target =
LocalDateRange.of(
LocalDate.of( … ) ,
LocalDate.of( … )
)
;
…和:
LocalDateRange selected =
LocalDateRange.of(
startJavaSqlDate.toLocalDate() ,
stopJavaSqlDate.toLocalDate()
)
;
比较。
boolean enclosed = target.encloses( selected ) ;
您的isWithin-range函数运算符先例是错误的。同时检查是否缺少结束日期和开始日期的isSameDate。在您的代码中,如果用户startDate与您的dateRange开始日期相似,或者用户结束日期与数据范围结束日期相似,则返回false。正确实现如下isWithinRange函数。
return (selectedDate.after(startDate) || DateUtils.isSameDay(selectedDate, startDate)) && (selectedDate.before(endDate) || DateUtils.isSameDay(selectedDate, endDate));
不使用||运算符&;对于isWithinRange2Dates函数,如下所示。
return isWithinRange(selectedStartDate, startDate, endDate) || isWithinRange(selectedEndDate, startDate, endDate);