实际上,我们很多实际的业务发生是跨月、甚至是跨年的,这种情况下,可能要对这些业务按月进行拆分,比如2023年10月25日 至2024年2月24日,需要拆分出来以下4个月份阶段:
- 2023年10月25日 - 2023年10月31日;
- 2023年11月1日 - 2023年11月30日;
- 2023年12月1日-2023年12月31日;
- 2024年1月1日 - 2024年2月24日
再如以下数据:
如果要实现按月份的拆分,我们首先要参考前面的文章把每一行涉及的年月(序列)构建出来:
代码语言:javascript复制let
sy = Date.Year([开始日期]),
sm = Date.Month([开始日期]),
ey = Date.Year([结束日期]),
em = Date.Month([结束日期])
in {sy*12 sm-1..ey*12 em-1} //做了减1处理,方便后面转为月份数
构建出来后,我们即可以基于该序列转换为年月,同时将对应年月的开始日期和结束日期构建出来,具体公式如下:
代码语言:javascript复制List.Transform(
[自定义],
(x)=>{
List.Max({[开始日期], #date(Number.IntegerDivide(x,12),Number.Mod(x,12) 1,1)}),
List.Min({[结束日期],Date.EndOfMonth(#date(Number.IntegerDivide(x,12),Number.Mod(x,12) 1,1))})
}
)
其中,涉及到一个很巧妙的算法,如月份开始日期:
代码语言:javascript复制List.Max({
[开始日期], //用开始日期和当月1月作对比,取大者即为所需结果
#date(
Number.IntegerDivide(x,12), //计算得到年
Number.Mod(x,12) 1, //计算得到月
1 //当月1日
)
})
如下图所示,显然,在开始日期所在当月,开始日期比当月1日大,通过List.Max即可取到开始日期,而对于后面的月份,相应月份的1日比开始日期大,也同样可以取到正确的月份开始日期。
关于结束日期和开始日期的处理方法类似,建议多动手画一下相应的图表示意图,很多问题的解决,往往就是在多动手尝试的过程中,不断理清思路,找到解决方案或者技巧的。