moment.js 给定时间 获取历史自然月、周的时间轴

2,271 阅读2分钟

1.需求

请添加图片描述 要实现这个时间轴的自然周、自然月的选择功能,需要思考两个问题

  1. 处理给定时间的本周与本月时间的显示,如输入 2021-07-29,最后一个月就是 2021-07-01 - 2021-07-29,最后一周就是 2021-07-26 - 2021-07-29
  2. 获取往前的自然月和周的第一天和最后一天(每周固定七天好处理,每月的天数不确定,需要特殊处理)

2.给定时间 获取自然月、周的时间范围

处理周参数思路

moment().weekday(0) 设置日期为当前时区周一 moment().weekday(6) 设置日期为当前时区周日

处理月参数思路

先获取到当月的1号的时间戳 当月的1号的时间戳减去 24 * 3600 就是上个月最后一天,不管上个月有28、29、30还是31天,取到的一定是正确的值
const day1Unix = moment().date(1)).unix() // 获取当月 1 号日期时间戳
const dayLast = moment.unix(day1Unix - 24 * 3600) // 获得上个月最后一天日期

根据上面的思路

3.获取时间轴 list

// 导入moment 并设置时间区域为中国
import moment from 'moment'
moment.locale('zh-cn')
/**
 * 根据时间刻度 day week month 生成对应的时间段列表
 * step: 时间段刻度 day | week | month
 * num: 输出多少组数据
 * displayTimeFormat: 显示时间的格式(可自定义)
 * rangeTimeFormat: 时间范围的格式(可自定义)
 */
export const getRangeTimeList = function(
  step,
  num = 50,
  displayTimeFormat = 'YYYY年MM月DD日',
  rangeTimeFormat = 'YYYY-MM-DD'
) {
  let now = moment() // 当前日期
  let result: any[] = []
  const oneDayTime = 24 * 3600 // 一天的秒数 注意不是毫秒数
  let currentUnix = now.unix() // 当前unix时间戳

  const getTimeRange = (begin, end) => {
    return [begin.format(rangeTimeFormat), end.format(rangeTimeFormat)]
  }
  const getDisplayTime = (begin, end) => {
    return begin.format(displayTimeFormat) + '-' + end.format(displayTimeFormat)
  }

  if (step === 'day') {
    for (let k = 1; k <= num; k++) {
      const obj: any = {}
      const day = moment.unix(currentUnix)
      obj.timeRange = getTimeRange(day, day)
      obj.tooltip = getDisplayTime(day, day)
      result.push(obj)
      currentUnix -= oneDayTime
    }
  }
  if (step === 'week') {
    // 处理当前这周
    const lastWeek: any = {}
    const firstDay = moment(now).weekday(0)
    lastWeek.timeRange = getTimeRange(firstDay, now)
    lastWeek.tooltip = getDisplayTime(firstDay, now)
    currentUnix = firstDay.unix()
    result.push(lastWeek)
    // 处理剩余n-1周
    for (let k = 2; k <= num; k++) {
      const obj: any = {}
      const sunday = moment.unix(currentUnix - oneDayTime) // 当前周-时间戳减去一天 等于上周日时间戳
      const monday = moment(moment.unix(currentUnix - oneDayTime).weekday(0))
      obj.timeRange = getTimeRange(monday, sunday)
      obj.tooltip = getDisplayTime(monday, sunday)
      result.push(obj)
      currentUnix -= oneDayTime * 7
    }
  }
  if (step === 'month') {
    // 处理当前月
    const lastMonth: any = {}
    const firstDate = moment(now).date(1)
    lastMonth.timeRange = getTimeRange(firstDate, now)
    lastMonth.tooltip = getDisplayTime(firstDate, now)
    currentUnix = firstDate.unix()
    result.push(lastMonth)
    // 处理剩余n-1个月
    for (let k = 2; k <= num; k++) {
      const obj: any = {}
      const dayLast = moment.unix(currentUnix - oneDayTime) // 当前月第一天时间戳减去一天 等于上个月最后一天时间戳
      const n = dayLast.date()
      const day1 = moment(moment.unix(currentUnix - oneDayTime).date(1))
      obj.timeRange = getTimeRange(day1, dayLast)
      obj.tooltip = getDisplayTime(day1, dayLast)
      result.push(obj)
      currentUnix -= oneDayTime * n
    }
  }
  return result
}

测试一下

const day = getRangeTimeList('day')
const week = getRangeTimeList('week')
const month = getRangeTimeList('month')
console.log('🚀 ~ day', day)
console.log('🚀 ~ week', week)
console.log('🚀 ~ month', month)

得到 day

week

month