关于给定日期范围,生成相应的自然月区间
前言
前段时间,接到公司财务方的需求,原来的出账逻辑中,有一种商家是周结的出账周期,顾名思义,就是每个星期一的凌晨去跑上个星期的账单数据,给商家出账。但是,如果说,如果这个星期如果跨了月,那财务需要把这些账单进行拆分,有一定的工作量,因此想在出账的时候,就进行拆分,方便财务核对。
思路
接到这个需求,思路无非就是,把这个出账的周期拆成两个账期,但是看了出账的逻辑,就是如果这个账期如果是没有数据,那这个账期就会跳过,不出帐,那这样的话,有一种极有有可能的情况是,这个时间区间跨了好几个月。按照产品经理的需求,那就把拆成每一个自然月。也就是说,2023-07-09 至 2023-09-20,要拆分成 2023-07-09至 2023-07-31,2023-08-01至2023-08-31,2023-09-01至2023-09-20。那开发的思路就不会很难理解,首先,我们要算出这个日期区间相隔多少个自然月,然后再把区间给求出来。
过程
第一步,本来觉得这个应该不难,直接利用现有的工具。以下代码示例
利用Java8新特性
String text1 = "2019-03-25";
Temporal startDate = LocalDate.parse(text1);
String text2 = "2022-05-30";
Temporal endDate = LocalDate.parse(text2);
long months = ChronoUnit.MONTHS.between(startDate, endDate);
System.out.println(months);
这里有个坑,就是这个算出来的并不是我们要的自然月,而且只在一些特殊的日期会有问题,因此被我弃用了。
后面又找了另一种,是引用Hutools的包
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.1.0</version>
</dependency>
Date startDateDay = new Date(1553443200000L);
Date endDateDay = new Date(System.currentTimeMillis());
long betweenMonth = DateUtil.betweenMonth(startDate, endDate, true);
System.out.println(betweenMonth);
但是结果也是不尽人意,总是感觉不太符合我的期望。
后面又在网上找了其他的,基本上都没有找到合适的,索性就自己写。
以下是我自己写的,希望大家指出不足之处,谢谢!!
public static Integer getDiffMonths(Date beginDate, Date endDate){
if(beginDate == null || endDate == null){
return null;
}
if(beginDate.compareTo(endDate) >= 0){
return null;
}
int beginYear = DateUtils.getYear(beginDate);
int endYear = DateUtils.getYear(endDate);
int beaginMonth = DateUtils.getMonth(beginDate);
int endMonth = DateUtils.getMonth(endDate);
//同一年
if(beginYear == endYear){
return endMonth - beaginMonth + 1;
}else {
return 12- beaginMonth + 1 + endMonth + (endYear-beginYear-1) * 12;
}
}
第二步,根据求出的月份数,算出区间
public static List<ShopTimeIntervalDTO> getTimeIntervalList(Date startDate, Date endDate){
if(startDate == null || endDate == null){
return null;
}
if(startDate.compareTo(endDate) >= 0){
return null;
}
List<ShopTimeIntervalDTO> dataList = new ArrayList<>();
Integer months = getDiffMonths(startDate, endDate);
if(months == null || months <= 0){
return dataList;
}
for(int i=0;i<months;i++){
Date start = getBeginDayOfMonth(addMonths(startDate, i));
Date end = getEndDayOfMonth(start);
if(i == 0){
start = startDate;
}
if(i == months-1){
end = endDate;
}
ShopTimeIntervalDTO data = new ShopTimeIntervalDTO();
data.setStartDate(start);
data.setEndDate(end);
dataList.add(data);
}
return dataList;
}
其中
public class ShopTimeIntervalDTO {
/**
* 开始时间
*/
private Date startDate;
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
/**
* 结束时间
*/
private Date endDate;
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
@Override
public String toString() {
return "ShopTimeIntervalDTO{" +
"startDate=" + startDate +
", endDate=" + endDate +
'}';
}
}
总结
其实功能并不复杂,重点是要先自己整理好思路,网上工具只是做参考,适合自己的才是最好的,谢谢大家!!!!
本文来自博客园,作者:it-小林,转载请注明原文链接:https://www.cnblogs.com/linruitao/p/17528841.html