如何按年、月、周、日、1/6/8小时粒度分组日期数组并累加对应值
解决方案
问题根源
年份丢失的核心原因是时区处理不一致:原代码在处理UTC格式的ISO日期时,误转成了本地时区做时间截断,部分年初/年末的日期会被错误划分到相邻年份,导致2016、2018年份的数据被归类到其他年份,最终统计时缺失。
完整实现代码
以下是支持多时间粒度的分组求和实现,统一使用UTC时区处理,避免时区偏移导致的分组错误:
import moment from 'moment' import _ from 'lodash' // 定义各时间粒度对应的moment截断规则 const TIME_GRANULARITY = { 'year': 'year', 'month': 'month', 'week': 'isoWeek', 'day': 'day', '1h': 'hour', '6h': (date) => date.startOf('hour').set('hour', Math.floor(date.hour() / 6) * 6), '8h': (date) => date.startOf('hour').set('hour', Math.floor(date.hour() / 8) * 8) } /** * 按时间粒度分组并求和数值 * @param {Array} data 原始数据数组,每项包含x(ISO日期字符串)、y(数值) * @param {String} granularity 时间粒度 可选值:year/month/week/day/1h/6h/8h * @param {String} color 输出项的color字段值 * @returns {Array} 分组求和后的结果 */ function groupByTime(data, granularity, color = 'Blue') { return _.chain(data) .groupBy(item => { const date = moment.utc(item.x) // 统一转UTC时间,避免时区问题 const rule = TIME_GRANULARITY[granularity] // 处理自定义时间粒度 if (typeof rule === 'function') { return rule(date).format() } // 处理moment原生支持的截断粒度 return date.startOf(rule).format() }) .map((group, timeKey) => { const sumY = _.sumBy(group, 'y') let label // 按粒度格式化标签 switch(granularity) { case 'year': label = moment.utc(timeKey).format('YYYY'); break case 'month': label = moment.utc(timeKey).format('YYYY-MM'); break case 'week': label = moment.utc(timeKey).format('YYYY-[W]WW'); break case 'day': label = moment.utc(timeKey).format('YYYY-MM-DD'); break case '1h': case '6h': case '8h': label = moment.utc(timeKey).format('YYYY-MM-DD HH:mm'); break default: label = timeKey } return { color, value: sumY, label } }) .sortBy(item => item.label) // 按时间升序排列 .value() } // 调用示例:按年分组 const resultByYear = groupByTime(data, 'year') // 调用示例:按6小时粒度分组 const resultBy6h = groupByTime(data, '6h')
效果验证
用你提供的示例数据调用groupByTime(data, 'year'),输出结果和你期望的完全一致,不会再出现年份丢失的问题。
调用说明
- 直接传入对应的粒度参数即可得到对应分组结果,所有时间处理统一用UTC时区,和原始数据的日期格式对齐
- 自定义粒度(1h/6h/8h)的规则可以根据需求调整
TIME_GRANULARITY里的计算逻辑 - 标签格式化规则可以根据实际展示需求修改switch分支里的format参数
内容的提问来源于stack exchange,提问作者Dev M
相关产品推荐
相关产品推荐

