封装生成指定间隔时间段的函数

最近工作中写 echarts 时,x轴坐标时间轴的间隔细粒度是动态控制的,比如按每2小时为间隔生成0点到4点的时间间隔

那么就需要得到一个这样的数组 ["00:00 - 02:00", "02:00 - 04:00"]

由于我的需求单位时间间隔是不固定的,所以来实现一个时间段分隔的函数

需求

首先我们拆分下需求,确定好这个函数需要干什么

  1. 根据指定间隔生成时间数组,如每两小时
  2. 可以指定开始时间以及结束时间
  3. 时间格式默认定义为 HH:mm - HH:mm 分钟默认为0,不足2位需要补足
  4. 可以逆向生成

功能实现

首先先来完定义输入和输出, 输入为开始时间,结束时间以及间隔,输出为时间数组,暂时不考虑逆向生成的问题

ts 复制代码
function generatorTimeList(start: Number,end: Number,interval: Number): string[]

接下来完成需求,首先根据间隔生成时间数组

思路: 使用循环,每次循环后让开始时间增加间隔,当开始时间大于结束时间时,循环结束

js 复制代码
function generatorTimeList(start = 0, end = 24, interval = 2) {
  // 创建一个时间数组
  const timeList = []
  // 格式化时间
  const format = (time) => `${time.toString().padStart(2, '0')}:00`
  while (start < end) { // 判断开始时间是否小于结束时间,如果小于则循环生成时间数组
    // 需要得到的格式: 00:00 - 02:00 ....
    // 生成当前节点开始时间
    const left = format(start)
    // start + interval 生成当前节点结束时间
    const right = format(start + interval)
    // 拼接时间字符串并存入数组
    timeList.push(`${left} - ${right}`)
    // 每次循环后让开始时间增加间隔
    start += interval
  }
  return timeList
}

这样我们一个基础的函数就完成了,现在调用函数就可以生成从0点到24点的数组了

js 复制代码
generatorTimeList(10,18,2) 

// ["10:00 - 12:00", "12:00 - 14:00", "14:00 - 16:00", "16:00 - 18:00"]

逆向生成

逆向生成需要从当前的时间往前推算,比如现在是早上4点,我需要得到昨天22点的值得到如下所示的结果

js 复制代码
generatorTimeList(4,22,2,true) 

// ["22:00 - 24:00", "00:00 - 02:00", "02:00 - 04:00"]

思路:代入上述参数.将结束时间当作开始时间即22点,生成到24点,然后从24点开始生成到开始时间即4点

js 复制代码
function generatorTimeList(start = 0, end = 24, interval = 2, isReverse = false) {
  const timeList = []
  const format = (time) => `${time.toString().padStart(2, '0')}:00`
  // 提取出一个生成时间段的函数,无需操心逆向逻辑
  const _generator = (start, end, step) => {
    while (start < end) {
      const left = format(start)
      const right = format(start + interval)
      timeList.push(`${left} - ${right}`)
      start += interval
    }
  }
  // 判断是否逆向生成,手动调用内部函数,传递不同参数来生成
  if (isReverse) {
    // 先生成结束时间到24点的时间段
    _generator(end, 24, interval)
    // 生成24(0)点到开始时间的时间段
    _generator(0, start, interval)
  } else {
    // 正常顺序逻辑 
    _generator(start, end, interval)
  }
  return timeList
}

发现问题

目前我们的代码还有一点小问题

js 复制代码
// 指定时间
generatorTimeList(10,24,2) 
[
    "10:00 - 12:00",
    "12:00 - 14:00",
    "14:00 - 16:00",
    "16:00 - 18:00",
    "18:00 - 20:00",
    "20:00 - 22:00",
    "22:00 - 24:00"
]

// 逆向生成
generatorTimeList(10,22,2,true) 
[
    "22:00 - 24:00",
    "00:00 - 02:00",
    "02:00 - 04:00",
    "04:00 - 06:00",
    "06:00 - 08:00",
    "08:00 - 10:00"
]

上述代码看起来运转正常,但是我们在参数上稍加修改,就会发现结果不对了

js 复制代码
generatorTimeList(10,24,8) 
[
    "10:00 - 18:00",
    "18:00 - 26:00" 
]
// 26:00 ??? 
generatorTimeList(10,4,2,true) 
[
    "04:00 - 06:00",
    "06:00 - 08:00",
    "08:00 - 10:00",
    "10:00 - 12:00",
    "12:00 - 14:00",
    "14:00 - 16:00",
    "16:00 - 18:00",
    "18:00 - 20:00",
    "20:00 - 22:00",
    "22:00 - 24:00",
    "00:00 - 02:00",
    "02:00 - 04:00",
    "04:00 - 06:00",
    "06:00 - 08:00",
    "08:00 - 10:00" 
    
]
// 应该返回 ["04:00-06:00", "06:00-08-00", "08:00-10:00"]

上述代码中我们看到有3个问题

  1. 当时间间隔过大的时候,会出现时间大于24小时的情况,
  2. 逆向生成时,如果结束时间小于开始时间,则结果与预期不正确
  3. 如果时间间隔大于结束时间也会有此问题

问题分析

问题1: 是由于上一次累加的开始时间加间隔后,超过了24小时,我们只需要判断是否大于24,如果大于24,默认结束值为24即可

问题2: 逆向生成时,假设开始时间为10点,结束时间为6点,我们想要的结果是6-8,8-10,但是代码中逆向逻辑,会先将结束时间生成到24点,在从0点生成到开始时间,所以结果不对

问题3: 由于代码中需要生成到24点在从0点开始,所以单数开始时间会无法根据双数间隔生成到结束时间

解决问题 && 最终代码

js 复制代码
function generatorTimeList(timeStart = 0, timeEnd = 24,interval = 2,  isReverse = false) {
  const timePoint = [];
  const formatTime = (hour) => `${hour.toString().padStart(2, '0')}:00`
  const _generator = (start, end, step) => {
    while (start < end) {
      const leftHour = formatTime(start)
      const rightHour = formatTime(Math.min((start + step), end))
      timePoint.push(leftHour + '-' + rightHour)
      start += step
    }
  }
  if (isReverse) {
    if (timeStart <= timeEnd) {
      _generator(timeEnd, 24, interval)
      _generator(0, timeStart, interval)
    }
    _generator(timeEnd, timeStart, interval)
  } else {
    _generator(timeStart, timeEnd, interval)
  }
  return timePoint;
}
js 复制代码
generatorTimeList(10,24,8) 
// ['10:00-18:00', '18:00-24:00']

generatorTimeList(10,4,2,true) 
// ['04:00-06:00', '06:00-08:00', '08:00-10:00']

上述代码进行了一些兜底操作,基本就可以正常按照指定的开始时间,结束时间,间隔时间,以及是否反向生成来运行了!

后续根据这个函数进行一些格式化定义,时间粒度的改造基本就能实现我的需求了

新人小白一个,只能想到这样来实现了,各位大佬有好的方法,或者这个功能有现成的实现方式欢迎留言~

相关推荐
吕彬-前端39 分钟前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱41 分钟前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
guai_guai_guai1 小时前
uniapp
前端·javascript·vue.js·uni-app
bysking2 小时前
【前端-组件】定义行分组的表格表单实现-bysking
前端·react.js
王哲晓2 小时前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js
fg_4112 小时前
无网络安装ionic和运行
前端·npm
理想不理想v2 小时前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
酷酷的阿云2 小时前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js
微信:137971205872 小时前
web端手机录音
前端
齐 飞2 小时前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb