如何在Javascript中实现按不同时间粒度的日期取整?
日期取整功能实现方案
第三方库方案
业内有成熟的JS日期库直接支持该需求,无需自己实现边界逻辑:
Day.js(轻量首选,体积仅2KB):内置通用endOf方法,传入对应时间粒度参数即可直接获取当前周期的最后一天,使用示例:
import dayjs from 'dayjs' const dates = [ "1/4/2020", "2/5/2021", "8/15/2021" ] // 按月取整 const monthResult = dates.map(d => dayjs(d, 'M/D/YYYY').endOf('month').format('M/D/YYYY')) // 按年取整 const yearResult = dates.map(d => dayjs(d, 'M/D/YYYY').endOf('year').format('M/D/YYYY')) // 其他粒度直接替换参数即可:week(周)、quarter(季度)
date-fns(功能更全):提供了独立的endOfWeek/endOfMonth/endOfQuarter/endOfYear方法,不可变设计不会修改原日期对象,适合对可靠性要求高的场景。
原生JS通用实现方案
如果不想引入第三方依赖,可以直接使用以下通用函数,覆盖所有时间粒度需求,自动处理闰年、月份天数差异等边界问题:
/** * 获取日期对应时间粒度的周期最后一天 * @param {string|Date} date 输入日期 * @param {string} granularity 时间粒度:可选值 week/month/quarter/year * @returns {string} 格式化后的M/D/YYYY格式日期 */ function dateEndOf(date, granularity) { const targetDate = new Date(date) const year = targetDate.getFullYear() let month = targetDate.getMonth() // 周粒度单独处理 if (granularity === 'week') { const weekDay = targetDate.getDay() targetDate.setDate(targetDate.getDate() + 6 - weekDay) return new Intl.DateTimeFormat('en-US').format(targetDate) } // 其他粒度计算目标月份 switch(granularity) { case 'year': month = 11 break case 'quarter': month = Math.floor(month / 3) * 3 + 2 break case 'month': // 无需修改月份 break } // 下个月第0天即为当前月最后一天 const endDate = new Date(year, month + 1, 0) return new Intl.DateTimeFormat('en-US').format(endDate) } // 使用示例 const dates = [ "1/4/2020", "2/5/2021", "8/15/2021" ] // 按月取整 console.log(dates.map(d => dateEndOf(d, 'month'))) // 按年取整 console.log(dates.map(d => dateEndOf(d, 'year')))
内容的提问来源于stack exchange,提问作者mmz
相关产品推荐
相关产品推荐

