最近工作中写 echarts
时,x轴坐标时间轴的间隔细粒度是动态控制的,比如按每2小时为间隔生成0点到4点的时间间隔
那么就需要得到一个这样的数组 ["00:00 - 02:00", "02:00 - 04:00"]
由于我的需求单位时间间隔是不固定的,所以来实现一个时间段分隔的函数
需求
首先我们拆分下需求,确定好这个函数需要干什么
- 根据指定间隔生成时间数组,如每两小时
- 可以指定开始时间以及结束时间
- 时间格式默认定义为
HH:mm - HH:mm
分钟默认为0,不足2位需要补足 - 可以逆向生成
功能实现
首先先来完定义输入和输出, 输入为开始时间,结束时间以及间隔,输出为时间数组,暂时不考虑逆向生成的问题
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个问题
- 当时间间隔过大的时候,会出现时间大于24小时的情况,
- 逆向生成时,如果结束时间小于开始时间,则结果与预期不正确
- 如果时间间隔大于结束时间也会有此问题
问题分析
问题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']
上述代码进行了一些兜底操作,基本就可以正常按照指定的开始时间,结束时间,间隔时间,以及是否反向生成来运行了!
后续根据这个函数进行一些格式化定义,时间粒度的改造基本就能实现我的需求了
新人小白一个,只能想到这样来实现了,各位大佬有好的方法,或者这个功能有现成的实现方式欢迎留言~