dayjs这样处理业务是不是更简便

794 阅读4分钟

dayjs 是一个轻量的日期处理插件

在业务场景中,难免需要处理各种日期问题,例如:

  • 获取一周前的时间
  • 查询最近一个月的数据
  • 查询最近3个月的数据
  • 查询一年的数据
  • ...等

难道我们每次都需要记忆这些计算方式吗? 不! 作为一个程序员,我们应该不断的总结已有的经验 , 达到,write once, copy to any project.

7天之前

import dayjs from 'dayjs'

// 先设置初始小时分钟秒. 再进行减法操作, 然后再格式化
dayjs().startOf('day').subtract(1, 'week').format('YYYY-MM-DD HH:mm:ss')

获取几天之前

function getPrevDay(n) {
    return dayjs().startOf('day').subtract(24 * n, 'hour').format('YYYY-MM-DD HH:mm:ss')
}

// 使用
getPrevDay(2) // 获取2天之前的日期

设置小时分钟秒

// "2021-04-12 00:00:00"
dayjs().startOf('day').format('YYYY-MM-DD HH:mm:ss')

// "2021-04-12 23:59:59"
dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss') 

获取 本周, 上周, 上上周的开始时间 至今 , 时间段

typescript 版本


/**
 * 获取某周的开始时间和结束时间
 */
const someWeek = (type: number) => {
  const t = dayjs()
  const mode = [
    {
      text: '本周',
      type: 1,
      time: t
    },
    {
      text: '上周',
      type: 2,
      time: t.subtract(1, 'week')
    },
    {
      text: '上上周',
      type: 3,
      time: t.subtract(2, 'week')
    }
  ]

  // ! 为断言, 表示find一定能找到一条item
  let startTime = mode.find((item) => item.type === type)!.time

  // .startOf('week') 是从星期天开始,所以,先设置为星期天的00:00:00 再加24小时
  return {
    beginDateTime: dayjs(startTime).startOf('week').add(24, 'hour').format('YYYY-MM-DD HH:mm:ss'),
    endDateTime: dayjs(startTime).hour(23).minute(59).second(59).format('YYYY-MM-DD HH:mm:ss')
  }
}

// 使用
someWeek(1)

取某个月的开始时间截止到今天

typescript 版本

/**
 * 获取某个月的开始时间截止到今天
 * @param t
 */
const someMonth = (t = new Date(), mode: OpUnitType) => {
  let beginDateTime = dayjs(t).startOf(mode).format('YYYY-MM-DD HH:mm:ss')
  let endDateTime = dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss')

  return {
    beginDateTime,
    endDateTime
  }
}

当前日期,往前几个月

/**
 * 往前几个月
 */
export const prevMonth = (t) => {
  return {
    startTime: dayjs().subtract(t, 'month').startOf('month').format('YYYY-MM-DD HH:mm:ss'),
    endTime: dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss')
  }
}


// 前3个月
prevMonth(2)

// 前6个月
prevMonth(5)

// 前12个月
prevMonth(11)

本年

/**
 * 本年
 */
export const currentYear = () => {
  return {
    startTime: dayjs().startOf('year').format('YYYY-MM-DD HH:mm:ss'),
    endTime: dayjs().format('YYYY-MM-DD HH:mm:ss')
  }
}

上一年

上一年的思路是: 拿到今年的 1月1日, 然后减去24小时, 得到时间 t , 再使用 t 去获取年的开始时间, 结束时间

/**
 * 上一年
 */
export const prevYear = () => {
  const currentYearStartTime = currentYear().startTime

  const prevYearLastDay = dayjs(currentYearStartTime).subtract(24, 'hour')
  return {
    startTime: dayjs(prevYearLastDay).startOf('year').format('YYYY-MM-DD HH:mm:ss'),
    endTime: dayjs(prevYearLastDay).endOf('day').format('YYYY-MM-DD HH:mm:ss')
  }
}

指定月份的最近12个月日期区间

import dayjs from 'dayjs'

/**
 * 返回指定月份的最近12个月日期区间
 * @example
 * getMonthRange('2022-03') -> 2021-04~2022-03
 */
export const getMonthRange = (t: Date | string | number = new Date) => {
  let endTime = dayjs(t).format('YYYY-MM')
  let startTime = dayjs(endTime).subtract(11, 'month').format('YYYY-MM')

  return {
    startTime,
    endTime
  }
}

批量获取小时的一半

let dayjs = require('dayjs')

const generateHalfDate = (date = new Date(), n) => {
  let list = []

  // 获取当前时间的分钟数
  let currentMinute = dayjs(date).get('minute')

  let start = null

  // 如果当前的分钟小于30, 例如:02:29  取02:30
  if (currentMinute < 30) {
    let c = dayjs(date).set('minute', 30)
    list.push({
      year: c.format('YYYY'),
      month: c.format('MM'),
      date: c.format('DD'),
      half: c.format('HH:mm'),
      full: dayjs(c).format('YYYY-MM-DD HH:mm')
    })
    start = c
  } else {
    // 取小时,比如当前分钟是 03:59分,取小时4:00
    let nextHour = dayjs(date).set('minute', 0).add(1, 'hour')

    list.push({
      year: nextHour.format('YYYY'),
      month: nextHour.format('MM'),
      date: nextHour.format('DD'),
      half: nextHour.format('HH:mm'),
      full: dayjs(nextHour).format('YYYY-MM-DD HH:mm')
    })

    start = nextHour
  }

  // 然后遍历, 重复n-1次
  for (let i = 0; i < n - 1; i++) {
    start = start.add(30, 'minute')

    list.push({
      year: start.format('YYYY'),
      month: start.format('MM'),
      date: start.format('DD'),
      half: start.format('HH:mm'),
      full: dayjs(start).format('YYYY-MM-DD HH:mm')
    })
  }

  return list
}

console.log(generateHalfDate(new Date('2022-03-15 00:59:00'), 10))

结果

[
  { year: '2022', month: '03', date: '15', half: '01:00', full: '2022-03-15 01:00' },
  { year: '2022', month: '03', date: '15', half: '01:30', full: '2022-03-15 01:30' },
  { year: '2022', month: '03', date: '15', half: '02:00', full: '2022-03-15 02:00' },
  { year: '2022', month: '03', date: '15', half: '02:30', full: '2022-03-15 02:30' },
  { year: '2022', month: '03', date: '15', half: '03:00', full: '2022-03-15 03:00' },
  { year: '2022', month: '03', date: '15', half: '03:30', full: '2022-03-15 03:30' },
  { year: '2022', month: '03', date: '15', half: '04:00', full: '2022-03-15 04:00' },
  { year: '2022', month: '03', date: '15', half: '04:30', full: '2022-03-15 04:30' },
  { year: '2022', month: '03', date: '15', half: '05:00', full: '2022-03-15 05:00' },
  { year: '2022', month: '03', date: '15', half: '05:30', full: '2022-03-15 05:30' }
]

获取2个日期之间的具体日期列表

背景:

实际的业务场景中,我们有开始日期,结束日期,但是想拿到2个日期之间的天数的List

import dayjs from 'dayjs'
/**
 * 获取2个日期之间具体天数的List
 * @param startTime 已经是标准的 2022-01-01
 * @param endTime 已经是标准的 2022-01-03
 * @returns ['2022-01-01', '2022-01-02', '2022-01-03']
 */
export const getDateRangeList = (startTime, endTime) => {
  let list = []

  // 差距的天数
  let t = dayjs(endTime).diff(startTime, 'day')
  for(let i=0; i<t; i++) {
    let nextTime = dayjs(startTime).add(i, 'day').format('YYYY-MM-DD')
    list.push(nextTime)
  }

  list.push(endTime)

  return list
}

最近7天的开始时间~结束时间

import dayjs from 'dayjs'

/**
 * 返回最近7天的开始时间~结束时间
 * @param t
 * @example
 * getDateRange('2022-01-12')
 * getDateRange(new Date('2022-01-12 12:22:23'))
 * getDateRange(1641961343000)
 */
export const getDateRange = (t: Date | string | number = new Date) => {
  let endTime = dayjs(t).endOf('day').format('YYYY-MM-DD')
  let startTime = dayjs(endTime).subtract(6, 'day').format('YYYY-MM-DD')

  return {
    startTime,
    endTime,
    range: getDateRangeList(startTime, endTime)
  }
}

返回指定日期所在周一到周日

typescript版本

import dayjs from 'dayjs'

/**
 * 返回指定日期所在周一到周日
 * @param t
 * getWeekRange('2022-01-12')
 * getWeekRange(new Date('2022-01-12 12:22:23'))
 * getWeekRange(1641961343000)
 */
export const getWeekRange = (t: Date | string | number = new Date) => {
  let endTime = dayjs(t).endOf('day').format('YYYY-MM-DD')
  let startTime = ''

  // 如果选择的日期为周日,周日在国外为一周的第一天
  const isSunday = dayjs(endTime).day() === 0

  if (isSunday) {
    // 减去24小时,是周六,startOf('week') 是周日, 在加1天,就是周一
    startTime = dayjs(endTime).subtract(24, 'hour').startOf('week').add(24, 'hour').format('YYYY-MM-DD')
    endTime = dayjs(endTime).format('YYYY-MM-DD')
  } else {
    startTime = dayjs(endTime).startOf('week').add(24, 'hour').format('YYYY-MM-DD'),
      endTime = dayjs(endTime).endOf('week').add(24, 'hour').format('YYYY-MM-DD')
  }

  return {
    startTime,
    endTime,
    range: getDateRangeList(startTime, endTime)
  }
}

getDateRangeList 是上面的 获取2个日期之间的具体日期列表

tips: 上面很多方法都返回 开始时间结束时间, 成对返回, 最大程度上提供业务层面的便利

微微余光,照亮你我,喜欢就点个赞呗! 😁😁😁

掘金文章主题和代码高亮使用配置如下:

highlight: monokai theme: fancy