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

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

}]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
  })
}

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




目录
相关文章
恢复时间目标(RTO, Recovery Time Objective)缩短
恢复时间目标(RTO, Recovery Time Objective)缩短
805 2
|
8月前
|
JavaScript 前端开发
JavaScript小技巧:数组去重的几种优雅写法
JavaScript小技巧:数组去重的几种优雅写法
620 142
|
6月前
|
弹性计算 运维 Shell
效率翻倍!3个自动化脚本(附源码),解决80%日常重复工作
运维人常被重复操作拖累?分享3个阿里云ECS高频自动化脚本:①批量巡检(CPU/内存/磁盘告警);②日志自动清理(7天+定时执行);③Python批量重启服务(基于阿里云SDK)。均经生产验证,轻量易用、开箱即用,助你释放80%重复劳力!
|
存储 Java 关系型数据库
基于springboot的宠物领养饲养交流系统
宠物领养饲养交流管理平台基于Java与SSM框架,结合MySQL数据库,实现信息高效管理。系统支持实时查询、修改与互动,提升用户体验,满足现代宠物爱好者对便捷化、信息化服务的需求,助力宠物领养推广与管理智能化发展。
|
缓存 JavaScript 前端开发
2024 前端高频面试题之 Vue 篇
2024 前端高频面试题之 Vue 篇
2325 8
|
安全 算法 数据安全/隐私保护
远控安全进阶之战:TeamViewer/ToDesk/向日葵设备安全策略对比
在数字化时代,卓越的远程控制软件需兼顾功能与体验,包括流畅连接、高清画质、低门槛UI设计、毫秒级延迟及多功能性,同时要有独树一帜的远控安全技术,通过前瞻性安全策略阻挡网络风险,为用户打造全方位安全体验,在基础安全防护上不断创新。本文选取了当下热门的TeamViewer、ToDesk、向日葵三款远程控制软件,从软件介绍、远控安全策略等多个维度进行深入对比,以呈现一场精彩的远控软件安全进阶“大比拼”。
|
10月前
|
人工智能 缓存 自然语言处理
AI网关可能是当下降低推理成本最经济的工程手段
网关成大模型降本关键:无需修改代码,即可节省达 70% 推理开销。
644 4
|
11月前
|
消息中间件 存储 Java
消息中间件RabbitMQ(高级)
本文深入探讨RabbitMQ在生产环境中的高级应用,涵盖消息可靠性、延迟消息、消息堆积及集群高可用等核心问题。通过生产者确认、持久化、消费者确认机制确保消息不丢失;利用TTL与死信交换机实现延迟队列;借助惰性队列提升堆积能力;最后通过普通集群、镜像集群及仲裁队列实现高可用架构。
 消息中间件RabbitMQ(高级)
|
机器学习/深度学习 数据挖掘 定位技术
多元线性回归:机器学习中的经典模型探讨
多元线性回归是统计学和机器学习中广泛应用的回归分析方法,通过分析多个自变量与因变量之间的关系,帮助理解和预测数据行为。本文深入探讨其理论背景、数学原理、模型构建及实际应用,涵盖房价预测、销售预测和医疗研究等领域。文章还讨论了多重共线性、过拟合等挑战,并展望了未来发展方向,如模型压缩与高效推理、跨模态学习和自监督学习。通过理解这些内容,读者可以更好地运用多元线性回归解决实际问题。
2322 0
|
缓存 自然语言处理 JavaScript
万字长文深度解析JDK序列化原理及Fury高度兼容的极致性能实现
Fury是一个基于JIT动态编译的高性能多语言原生序列化框架,支持Java/Python/Golang/C++/JavaScript等语言,提供全自动的对象多语言/跨语言序列化能力,以及相比于别的框架最高20~200倍的性能。
169555 12