1. 判断时间段是否合法;
2. 循环判断记录数是否大于0
3. 根据起始时间算出该月的第一天、最后一天和这个月有多少天;
4. 判断起始时间是否是该月第一天,如果是,再判断结束时间与该月最后一天的大小:小于,等于,大于;
5. 判断起始时间是否是该月第一天,如果不是,再判断结束时间与该月最后一天的大小:小于,等于,大于;
这里的LocalDate是Java8中的时间类,只有日期,没有时分秒等;如2018-03-26。
下面函数仅仅只需要接受两个LocalDate参数(一个时间段),就可以获得该时间段内由哪些日期和哪些月份组成;
Date、long转LocalDate等更多时间常用操作可以参考:https://www.cnblogs.com/theRhyme/p/9756154.html。
具体代码如下:
public void accordingToCountCalcData(LocalDate start,LocalDate end){
//这里的count表示自定义时间段内需要累加的记录的条数
final long count = end.toEpochDay() - start.toEpochDay() + 1;
if(count < 1){
log.error("startTime can't greater than endTime",new IllegalArgumentException("startTime can't greater than endTime"));
return;
}
log.info("******BEGIN: There are {} records between {} and {}. ******",count,start,end);
long num = count;
while(num > 0) {
LocalDate firstDay = start.with(TemporalAdjusters.firstDayOfMonth());
LocalDate lastDay = start.with(TemporalAdjusters.lastDayOfMonth());
//该月有多少天
int dayOfMonth = lastDay.getDayOfMonth();
if (firstDay.compareTo(start) == 0) {
//传入的起始时间如果是当月的第一天
if (lastDay.compareTo(end) == 0) {
//传入的结束时间和开始时间构成了完整一个月
num = num - lastDay.getDayOfMonth();
log.info("{} and {} which making up a full month",firstDay,lastDay);
} else if (end.compareTo(lastDay) > 0) {
//包含了完整的一个月
log.info("Accumulating {} to {} , {} records",start,lastDay,dayOfMonth);
num = num - dayOfMonth;
//下个月的这天
start = start.minusMonths(-1);
//下个月的1号
start = LocalDate.of(start.getYear(),start.getMonthValue(),1);
} else if (end.compareTo(lastDay) < 0) {
log.info("Accumulating {} to {} , {} records.",start,end,num);
num = 0;
}
}else if(start.compareTo(firstDay) > 0) {
//传入的开始时间不是当前月的第一天
if (end.compareTo(lastDay) <= 0) {
log.info("Accumulating {} to {} , {} records.", start, end, num);
num = 0;
} else if (end.compareTo(lastDay) > 0) {
//先累加从开始时间到这个月最后一天的记录
Period p = Period.between(start, lastDay);
//这里还减1是因为两个日期如果相差11天,就有12条纪录
int records = p.getDays() + 1;
log.info("Accumulating {} to {} , {} records.", start, lastDay, records);
num = num - records;
//下个月的这天
start = start.minusMonths(-1);
//下个月的1号
start = LocalDate.of(start.getYear(), start.getMonthValue(), 1);
}
}
}
log.info("****** End: Function \"accordingToCountCalcData\". ******");
}
测试结果如下:
在线日期工具:
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 开发者新选择:用DeepSeek实现Cursor级智能编程的免费方案
· Tinyfox 发生重大改版
· 独立开发经验谈:如何通过 Docker 让潜在客户快速体验你的系统
· 小米CR6606,CR6608,CR6609 启用SSH和刷入OpenWRT 23.05.5
· 近期最值得关注的AI技术报告与Agent综述!