之前有这么一个小需求:设定每周六到下周五为一个周期,输入一个日期,获取这个日期所在周期的开始日期和结束日期。
这个需求不算很常见,起码在我公司的业务中不算常见。编写当然也没问题,实例代码如下:
public static void main(String[] args) {
Date inputDate = new Date(); // 示例输入日期,通常从数据库或API接收
Pair<Date, Date> weekCycle = getWeekCycle(inputDate);
System.out.println("周期开始日期: " + formatDate(weekCycle.getKey()));
System.out.println("周期结束日期: " + formatDate(weekCycle.getValue()));
}
public static Pair<Date, Date> getWeekCycle(Date inputDate) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(inputDate);
// 找到本周的周六
if(calendar.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY) {
calendar.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
calendar.add(Calendar.WEEK_OF_YEAR, -1);
}
Date cycleStart = calendar.getTime();
// 从周六开始,找到下一个周五
while (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.FRIDAY) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
Date cycleEnd = calendar.getTime();
return Pair.of(cycleStart, cycleEnd);
}
private static String formatDate(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(date);
}
}
calendar有一个要注意的地方是,在获取dayOfWeek的时候,是从周日开始的,即周日是1,周一是2…一直到周六是7。
在我的代码中,找到本周的周六以后,要减掉一周。
当输入日期时周一到周五时,此时设置的周六是下个周期的开始的周六,本周期的周六要减去一周,即上周的周六才是本周期开始的日期。
当输入的日期是周日的时候,周六开始到下周五,周日不是正好在这个周期里面吗,为啥此时为什么还要减1呢?
这就说到了刚才周日是1,周六是7的问题。在calendar中,一星期是从周日开始的,你从这个周日开始获取到的周六,实际是下周的周六,而不是我们在日历中看到的本周的周六,所以这里还得减掉1,才是真正这周期开始的周六的日期。
至于找到结束的周五就没啥难度了,因为我们本身需要的就是下周五的日期,你直接在设置了周六的日期基础上,往下加到周五的日期,就是正确的结束日期。
实际上这个时候需求已经写完了,但是我最近在使用AI,于是我问了问AI,对话内容我就省略了,发现AI提供了一个新的方法几行就搞定。
public static void main(String[] args) {
// 示例输入日期,通常从数据库或API接收
Pair<LocalDate, LocalDate> weekCycle = getWeekCycle(LocalDate.now());
System.out.println("周期开始日期: " + weekCycle.getKey());
System.out.println("周期结束日期: " + weekCycle.getValue());
}
private Pair<LocalDate, LocalDate> getWeekCycle(LocalDate inputDate) {
DayOfWeek startingDay = DayOfWeek.SATURDAY;
LocalDate cycleStart = inputDate.with(TemporalAdjusters.previousOrSame(startingDay));
LocalDate cycleEnd = startingDay;
while (endDate.getDayOfWeek() != DayOfWeek.FRIDAY) {
cycleEnd = cycleEnd.plusDays(1);
}
return Pair.of(cycleStart, cycleEnd);
}
这里主要是用了一个没用过的方法TemporalAdjusters.previousOrSame,cycleEnd.plusDays。几行就搞定了,可以学一学,比起使用date和calendar是要简便一点。
唯一要考虑的就是输入时间类型的问题,当然这个也是小问题。
由于和我之前写的相比更加简洁,同时也是个我以前没有考虑的方法,所以我覆盖了我自己的方法提交到了项目中,并且在这里记录一下。希望能帮助到看着这篇小记的人。