生成以周统计的表头,跨月份的周算在后一个月

简介: 这是人力统计的一个表格的表头,根据月份,划分周,每周从周一开始到周日(国内习惯性)。而跨月份的周算在前一个月还是后一个月,我们的需求是算在后一个月。根据情况而定。

}]J}G2`AR5WA@)CWQ`~0]9F.png

这是人力统计的一个表格的表头,根据月份,划分周,每周从周一开始到周日(国内习惯性)。而跨月份的周算在前一个月还是后一个月,我们的需求是算在后一个月。根据情况而定。

SF`H3QW_N10OS)47)DSL8}Q.png


在表格中我们可以通过动态生成列,维护一个二维的数组,这个二维数组应该长得像这样

521O3B9~UPSMP%@}KO%LYU5.png


外层的属性 nameLabel 是显示在最上面的年月,weekData 对应的是一个数组显示的是下面的周起止日期和周序号 W1 - W5


我们再来看,如何得到一个这样的二维数组?

首先声明一个名为 generateWeeklyArray 的函数,参数为起止年月,格式为年月组成的数字类型好了,如 202108

generateWeeklyArray (startTime, endTime){}

这里为了方便日期转化,和计算,引入了 momnet 日期库


下面是具体的实现,我们对着代码具体讲解下

generateWeeklyArray (startTime, endTime) {
  startTime = moment(startTime).format('YYYY-MM-DD')
  endTime = moment(endTime).endOf('month').format('YYYY-MM-DD')
  let firstDay = new Date(startTime)
  let lastDay = new Date(endTime)
  let day = firstDay
  let weeklyData = []
  if (firstDay.getDay !== 1) {
    let realFirst = moment(day).add(-6, 'days').format('YYYY-MM-DD')
    day = new Date(realFirst)
  }
  while (day.getTime() < lastDay.getTime() || day.getTime() === lastDay.getTime()) {
    if (day.getDay() === 1) {
      let yearMonth = moment(day).format('YYYYMM')
      if (moment(day).format('M') < moment(day).add(6, 'days').format('M') || moment(day).format('YYYY') < moment(day).add(6, 'days').format('YYYY')) {
        yearMonth = moment(day).add(6, 'days').format('YYYYMM')
      }
      if (moment(day).format('YYYYMM') === moment(lastDay).format('YYYYMM') && moment(lastDay).format('YYYYMM') !== moment(day).add(6, 'days').format('YYYYMM')) {
        // console.log('下个月显示')
      } else {
        let weekRange = moment(day).format('M/D') + '-' + moment(day).add(6, 'days').format('M/D')
        weeklyData.push({
          nameProp: 'col' + yearMonth + weekRange.replace(/\/|-/g, ''),
          weekRange: weekRange,
          yearMonth: yearMonth
        })
      }
      day.setDate(day.getDate() + 7)
    } else {
      day.setDate(day.getDate() + 1)
    }
  }
  let weeklyColumnHeaders = []
  weeklyData.forEach(col => {
    let colName = 'col' + col.yearMonth
    let colItem = weeklyColumnHeaders.find(item => item.nameProp === colName)
    if (colItem) {
      weeklyColumnHeaders.map(item => {
        if (item.nameProp === colName) {
          item.weekData.push({
            weekRange: col.weekRange,
            nameProp: col.nameProp,
            weekNo: 'W' + (item.weekData.length + 1)
          })
        }
      })
    } else {
      weeklyColumnHeaders.push({
        nameProp: colName,
        nameLabel: col.yearMonth,
        weekData: [{weekRange: col.weekRange, nameProp: col.nameProp, weekNo: 'W' + 1}]
      })
    }
  })
  return weeklyColumnHeaders
}

这里主要的逻辑是在 while 循环中,以起止时间为条件,循环遍历找出周一的日期,通过向后推算六天,得到周的日期范围,组成数据添加到当前月份的 weekData 的数组中,当前数组的长度即为周的序号。

一般循环需要兼顾下两头的特殊情况,首先看开始的情况:当 startTime 月份的1号不是周一,就需要往前推几天,直到周一作为开始日期。

let day = firstDay
let weeklyData = []
if (firstDay.getDay !== 1) {
  let realFirst = moment(day).add(-6, 'days').format('YYYY-MM-DD')
  day = new Date(realFirst)
}

再来看结束时间的情况:如果 endTime 所在的月份的最后一周跨了月份,根据我们的规则,我们要把它算在下一个月里,这里要排除掉它

if (moment(day).format('YYYYMM') === moment(lastDay).format('YYYYMM') && moment(lastDay).format('YYYYMM') !== moment(day).add(6, 'days').format('YYYYMM')) {
  // console.log('下个月显示')
} else {
  let weekRange = moment(day).format('M/D') + '-' + moment(day).add(6, 'days').format('M/D')
  weeklyData.push({
    nameProp: 'col' + yearMonth + weekRange.replace(/\/|-/g, ''),
    weekRange: weekRange,
    yearMonth: yearMonth
  })
}

好了,这里的需要注意的地方就这些,其它的逻辑简单可以自己看代码。




目录
相关文章
|
6月前
|
数据库
指定月份显示每天的数据
指定月份显示每天的数据
|
3月前
|
Python
【已解决】如何获取到DF数据里最新的调薪时间,就是薪资最高且时间最早?
【已解决】如何获取到DF数据里最新的调薪时间,就是薪资最高且时间最早?
30 1
|
DataWorks 数据处理
DataWorks新加坡和香港查看表分区信息页面,记录数不显示,显示为“今日新增,明日数据更新”,这个是啥情况?
DataWorks新加坡和香港查看表分区信息页面,记录数不显示,显示为“今日新增,明日数据更新”,这个是啥情况?
111 1
|
JavaScript 前端开发
javascript以当前日期为准计算当月、上月、下月直接输出日期的解决方案
javascript以当前日期为准计算当月、上月、下月直接输出日期的解决方案
98 0
【SQL开发实战技巧】系列(十七):数据仓库中时间类型操作(初级)确定两个日期之间的工作天数、计算—年中周内各日期出现次数、确定当前记录和下一条记录之间相差的天数
如何确定两个日期之间的工作日有多少天、计算—年中每周内各日期出现次数、确定当前记录和下一条记录之间相差的天数【SQL开发实战技巧】这一系列博主当作复习旧知识来进行写作,毕竟SQL开发在数据分析场景非常重要且基础,面试也会经常问SQL开发和调优经验,相信当我写完这一系列文章,也能再有所收获,未来面对SQL面试也能游刃有余~。本章节的三个需求:确定两个日期之间的工作天数、计算—年中周内各日期出现次数、确定当前记录和下一条记录之间相差的天数有些许难度,不过建议还是学会比较好。
【SQL开发实战技巧】系列(十七):数据仓库中时间类型操作(初级)确定两个日期之间的工作天数、计算—年中周内各日期出现次数、确定当前记录和下一条记录之间相差的天数
使用周名数字来计算周的名称
使用周名数字来计算周的名称
76 0
|
API
用节假日api计算两个日期之间的工作日天数
   最近遇到要求两个日期之间的工作日天数的问题,于是自己思考,进行了一下简单处理。主要是在循环处理上进行了精简。然后利用节假日api 直接输出了两个日期之间的工作日,并且做了一些扩展.可以利用参数获取两个日期之间的工作日和节假日情况     要想获取天数的话直接count一下返回的data数量即可 接口文档地址:http://tool.
8731 0
|
SQL 关系型数据库 MySQL
MYSQL查询近一年 近一月 近一周 今天数据 没有数据返回0 按时间有序返回数据
MYSQL查询近一年 近一月 近一周 今天数据 没有数据返回0 按时间有序返回数据
684 0
MYSQL查询近一年 近一月 近一周 今天数据 没有数据返回0 按时间有序返回数据
SAP MM 采购信息记录中价格单位转换因子的修改
SAP MM 采购信息记录中价格单位转换因子的修改