/**
* 合同日期处理
* @AUTHOR: Lij
* @Date: 2021-03-30 13:38
* @DESCRIPTION:
* @Version: 1.0
*/
class ContractDate {
/**
* key值表示付费周期, value表示周期包含的月份数
*/
static final Map<Integer, Integer> CYCLE = [2:1, 3:3, 4:6, 5:12]
/**
* 按条件切割日期
* @param start 开始日期
* @param end 结束日期
* @param type 结算类型 [1:按自然月结算, 2:按日期结算]
* @param cycle 付费周期 [2:每月, 3:每季, 4:每半年, 5:每年]
* @return List<Map<String, Date>>
*/
static def splitMonth(Date start, Date end, int type, int cycle){
def monthArr = []
// 按自然月, 非严格
if(type == 0){
monthArr = nature(start, end, cycle)
}
// 按自然月, 严格
else if (type == 1){
monthArr = natureStrict(start, end, cycle)
}
// 按日期
else if(type == 2){
monthArr = dayWay(start, end, cycle)
}
return monthArr
}
/**
* 获取一个周期
* @param date 日期
* @param type 结算类型 [1:按自然月结算, 2:按日期结算]
* @param cycle 付费周期 [2:每月, 3:每季, 4:每半年, 5:每年]
* @return Map<String, Date>
*/
static Map<String, Date> getOneCycle(Date date, int type, int cycle){
def monthMap = new HashMap<String, Date>()
def startDate = date
if(type == 0){
startDate = addMonth(getBeginOfTheDayAfterThisDay(getMonthLastDay(date)), -CYCLE[cycle])
}
else if (type == 1){
startDate = getCycleFirstDay(date, cycle)
}
else if(type == 2){
startDate = getBeginOfThisDay(date)
}
def calcEndDate = addMonth(startDate, CYCLE[cycle])
def endDate = getEndOfTheDayBeforeThisDay(calcEndDate)
monthMap.startDate = startDate
monthMap.endDate = endDate
return monthMap
}
/**
* 按日期 计算分期时段
* <p>如按季度(cycle=3): </p>
* <p>4月14日到7月13日为一个时间段,</p>
* <p>7月14日到10月13日为下一个时间段,</p>
* <p>以此类推.</p>
* @param start 开始日期
* @param end 结束日期
* @param cycle 付费周期 [2:每月, 3:每季, 4:每半年, 5:每年]
* @return List<Map<String, Date>>
*/
static def dayWay(Date start, Date end, int cycle){
Date startDate = start
List<Map<String, Date>> monthArr = []
// 增量
def c = CYCLE[cycle]
while(startDate<=end){
def midDate = getBeginOfThisDay(startDate)
def midObj = [startDate: midDate]
// 增加 c 后的日期
def calcEndDate = addMonth(midDate, c)
// 结束日期 需要取前一天的 23:59:59
def endDate = getEndOfTheDayBeforeThisDay(calcEndDate)
// 如果 周期的最后一天 超过(大于)截止日期 则终止循环
if (endDate > end){
break
}
midObj.endDate = endDate
monthArr.push(midObj)
// 下一个开始日期
startDate = calcEndDate
}
if (startDate<=end){
monthArr.push([startDate: startDate, endDate: end])
}
return monthArr
}
/**
* 按自然周期(非严格)计算分期时段.
* <p>如按季度(cycle=3):</p>
* <p>4月14日到4月30日为一个时间段,</p>
* <p>5月1日到7月31日为下一个时间段,</p>
* <p>以此类推.</p>
* @param start 开始日期
* @param end 结束日期
* @param cycle 付费周期 [2:每月, 3:每季, 4:每半年, 5:每年]
* @return List<Map<String, Date>>
*/
static def nature(Date start, Date end, int cycle){
Date startDate = start
List<Map<String, Date>> monthArr = []
def dayOfMonth = getDayOfMonth(start)
def endDate = null
// 不是 1 号
if (dayOfMonth != 1){
def calcStart = getBeginOfThisDay(start)
def calcEnd = getMonthLastDay(start)
// 结束日期 需要取当天的 23:59:59
endDate = getEndOfThisDay(calcEnd)
monthArr.push([startDate:calcStart, endDate:endDate>end?end:endDate])
// 下一个开始日期
startDate = getBeginOfTheDayAfterThisDay(calcEnd)
}
if (endDate && endDate<end){
def list = dayWay(startDate, end, cycle)
monthArr.addAll(list)
}
return monthArr
}
/**
* 按自然周期(严格)计算分期时段.
* <p>如按季度(cycle=3):</p>
* <p>4月14日到6月30日为一个时间段,</p>
* <p>7月1日到9月30日为下一个时间段,</p>
* <p>以此类推.</p>
* @param start 开始日期
* @param end 结束日期
* @param cycle 付费周期 [2:每月, 3:每季, 4:每半年, 5:每年]
*/
static def natureStrict(Date start, Date end, int cycle){
Date startDate = start
List<Map<String, Date>> monthArr = []
def cycleFirstDay = getCycleFirstDay(start, cycle)
def endDate = null
if (start > cycleFirstDay){
def calcStart = getBeginOfThisDay(start)
def calcEnd = getCycleLastDay(start, cycle)
// 结束日期 23:59:59
endDate = getEndOfThisDay(calcEnd)
monthArr.push([startDate:calcStart, endDate:endDate>end?end:endDate])
// 下一个开始日期
startDate = getBeginOfTheDayAfterThisDay(calcEnd)
}
if (endDate && endDate<end){
def list = dayWay(startDate, end, cycle)
monthArr.addAll(list)
}
return monthArr
}
/**
* 在 date 的基础上增加(减少) increment 天
* @param date 日期
* @param increment 增量
*/
static def addDay(Date date, int increment){
return add(date, increment, Calendar.DAY_OF_MONTH)
}
/**
* 在 date 的基础上增加(减少) increment 月
* @param date 日期
* @param increment 增量
*/
static def addMonth(Date date, int increment){
return add(date, increment, Calendar.MONTH)
}
/**
* 在 date 的基础上增加(减少) increment 数量的 type
* @param date 日期
* @param increment 增量
* @param field 类型 如:Calendar.YEAR
*/
static Date add(Date date, int increment, int field){
def calendar = Calendar.getInstance()
calendar.setTime(date)
calendar.add(field, increment)
return calendar.getTime()
}
/**
* 获取当天 0 点 0 分 0 秒
* @param date 日期
* @return Date
*/
static Date getBeginOfThisDay(Date date){
Calendar c = Calendar.getInstance()
c.setTime(date)
c.set(c.get(Calendar.YEAR),c.get(Calendar.MONTH),c.get(Calendar.DAY_OF_MONTH),0,0,0)
c.set(Calendar.MILLISECOND,0)
return c.getTime()
}
/**
* 获取当天 23 点 59 分 59 秒
* @param date 日期
* @return Date
*/
static Date getEndOfThisDay(Date date){
Calendar c = Calendar.getInstance()
c.setTime(date)
c.set(c.get(Calendar.YEAR),c.get(Calendar.MONTH),c.get(Calendar.DAY_OF_MONTH),23,59,59)
c.set(Calendar.MILLISECOND,999)
return c.getTime()
}
/**
* 获取某个日期前一天的 23 点 59 分 59 秒
* @param date 日期
* @return Date
*/
static Date getEndOfTheDayBeforeThisDay(Date date){
def theDay = addDay(date, -1)
def theEnd = getEndOfThisDay(theDay)
return theEnd
}
/**
* 获取某个日期后一天的 0 点 0 分 0 秒
* @param date 日期
* @return
*/
static Date getBeginOfTheDayAfterThisDay(Date date){
def theDay = addDay(date, 1)
def theBegin = getBeginOfThisDay(theDay)
return theBegin
}
/**
* 获取当前日期中的日
* @param date 日期
* @return
*/
static int getDayOfMonth(Date date){
def c = Calendar.getInstance()
c.setTime(date)
return c.get(Calendar.DAY_OF_MONTH)
}
/**
* 获取当前日期中的月
* @param date 日期
* @return
*/
static int getMonth(Date date){
def c = Calendar.getInstance()
c.setTime(date)
return c.get(Calendar.MONTH)
}
/**
* 获取当前日期的年月日
* @param date 日期
* @return Map<String, Integer> yyyy:年, MM:月, dd:日
*/
static Map<String, Integer> getYmd(Date date){
def c = Calendar.getInstance()
c.setTime(date)
def res = [
yyyy:c.get(Calendar.YEAR),
MM:c.get(Calendar.MONTH),
dd:c.get(Calendar.DAY_OF_MONTH)
]
return res
}
/**
* 获取 日期所在周期的最后一天的日期
* @param date 日期
* @param cycle 付费周期 [2:每月, 3:每季, 4:每半年, 5:每年]
* @return 日期, 0 点 0 分 0 秒
*/
static Date getCycleLastDay(Date date, int cycle){
def inc = CYCLE[cycle]
def ymd = getYmd(date)
def month = ymd.MM + 1
def c = Calendar.getInstance()
def lastMonth = (Math.ceil(month / inc) * inc) as Integer
c.set(ymd.yyyy, lastMonth,0,0,0,0)
c.set(Calendar.MILLISECOND, 0)
return c.getTime()
}
/**
* 获取 日期所在月的最后一天的日期
* @param date 日期
* @return 日期, 0 点 0 分 0 秒
*/
static Date getMonthLastDay(Date date){
def c = Calendar.getInstance()
c.setTime(date)
c.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.getActualMaximum(Calendar.DAY_OF_MONTH),0,0,0)
c.set(Calendar.MILLISECOND, 0)
return c.getTime()
}
/**
* 获取 日期所在周期的第一天的日期
* @param date 日期
* @param cycle 付费周期 [2:每月, 3:每季, 4:每半年, 5:每年]
* @return 日期, 0 点 0 分 0 秒
*/
static Date getCycleFirstDay(Date date, int cycle){
def inc = CYCLE[cycle]
def ymd = getYmd(date)
def month = ymd.MM
def c = Calendar.getInstance()
def lastMonth = (Math.floor(month / inc) * inc) as Integer
c.set(ymd.yyyy, lastMonth,1,0,0,0)
c.set(Calendar.MILLISECOND, 0)
return c.getTime()
}
/**
* 获取 日期所在月的第一天的日期
* @param date 日期
* @return 日期, 0 点 0 分 0 秒
*/
static Date getMonthFirstDay(Date date){
def c = Calendar.getInstance()
c.setTime(date)
c.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), 1,0,0,0)
c.set(Calendar.MILLISECOND, 0)
return c.getTime()
}
static void main(String[] args){
def fmtStr = "yyyy-MM-dd HH:mm"
def startDate = new Date(1550000000000L)
def endDate = new Date(1600000000000L)
println "${startDate.format(fmtStr)}\tTO\t${endDate.format(fmtStr)}"
println "------------------------------------------------"
def type = 0, cycle = 3
def list = splitMonth(startDate, endDate, type, cycle)
list.sort {a,b->a.startDate<=>b.startDate}
list.each {
println "${it.startDate.format(fmtStr)}\t\t${it.endDate.format(fmtStr)}"
}
println "------------------------------------------------"
def one = getOneCycle(startDate, type, cycle)
println "startDate:\t${one.startDate.format(fmtStr)}"
println "endDate: \t${one.endDate.format(fmtStr)}"
println "------------------------------------------------"
}
}
08-03
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交