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

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

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

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




目录
相关文章
|
算法 调度 UED
深入理解操作系统内存管理:原理与实践
【4月更文挑战第23天】 在现代计算机系统中,操作系统的内存管理是保证系统高效、稳定运行的关键组成部分。本文旨在深入探讨操作系统中内存管理的理论基础、关键技术以及实际操作过程,通过对内存分配策略、虚拟内存技术、分页与分段机制等核心概念的详细解析,为读者提供一个清晰、全面的内存管理视角。此外,文章还将通过案例分析,展示内存管理在解决实际问题中的应用,以期加深读者对操作系统内存管理复杂性的认识和理解。
|
安全 中间件 Apache
【Web安全】不安全的HTTP方法
围绕渗透攻防层面来看不安全的HTTP方法漏洞的检测发现修复等手法。
1812 1
|
供应链 芯片
电商黑话之 spu sku
SPU = Standard Product Unit (标准化产品单元),SPU是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的基本特性。因此在电商类产品库建立时,通常会根据SPU来建立。
电商黑话之 spu sku
|
前端开发 安全 测试技术
逆向海淘代购集运系统客户案例:superbuy淘宝代购集运系统丨1688代采系统搭建攻略
搭建Superbuy淘宝代购及1688代采系统涉及定位分析、技术选型、API集成、支付物流、用户体验及安全部署。采用PHP、MVC架构,集成多平台商品、支付方式,确保数据同步与安全。1688代采系统着重商品代采、订单管理与物流跟踪,通过自动化流程提升效率。全面测试确保系统稳定可靠。
|
Java 数据库连接 编译器
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
245 0
|
敏捷开发 测试技术 持续交付
阿里云云效产品使用合集之消息通知不会触发邮件提醒是什么原因
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
编解码 安全 Ubuntu
Android Selinux 问题处理笔记
这篇文章是关于处理Android系统中SELinux权限问题的笔记,介绍了如何通过分析SELinux拒绝的日志、修改SELinux策略文件,并重新编译部署来解决权限问题,同时提供了一些SELinux的背景知识和实用工具。
1042 0
|
SQL Cloud Native 关系型数据库
云原生数据仓库操作报错合集之遇到报错“DDL forbidden because backupTask is doing snapshot”如何处理
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
|
存储 关系型数据库 数据库
RDS(Relational Database Service)性能瓶颈
RDS(Relational Database Service)性能瓶颈
345 4
|
数据采集 存储 运维
基于数据全生命周期的数据资产价值评估方法及应用
数据资产价值评估是现代数据资产管理和运营以及数据流通的基础。基于数据全生命周期理论,从第一性原则出发,通过评估单张数据资产表的成本、数据管理以及数据应用价值,实现对单张数据资产表的系统性评估。利用数据仓库和图算法等技术,以层为单位,每层分摊,血缘路径继承,精确计算得到单张数据资产表的成本价值;然后利用层次分析法得到数据资产非经济因素权重,进而得到数据资产阶梯价值;最后通过实例分析验证了新方法的合理性和可行性。