跨月数据怎么拆?这个精巧算法值得收藏!

2023-11-05 12:40:12 浏览数 (1)

实际上,我们很多实际的业务发生是跨月、甚至是跨年的,这种情况下,可能要对这些业务按月进行拆分,比如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日比开始日期大,也同样可以取到正确的月份开始日期。

关于结束日期和开始日期的处理方法类似,建议多动手画一下相应的图表示意图,很多问题的解决,往往就是在多动手尝试的过程中,不断理清思路,找到解决方案或者技巧的。

0 人点赞