js中常用的时间操作整理

652 阅读9分钟

“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情

工作中经常需要对时间进行一系列操作(格式化,转换,计算范围等),每次都需要去百度或者自己写一遍,为了方便日后使用,抽空整理一下。以下的一些方法是依赖dayjs,一个时间处理的JavaScript库。

为何使用dayjs

  • 文件大小只有2KB左右,下载、解析和执行的JavaScript更少,为代码留下更多的时间。
  • 所有更改Day.js对象的API操作都将返回一个新的实例。这有助于防止错误和避免长时间的调试会话。
  • Day.js对国际化有很大的支持

安装dayjs

  • vue中使用
// 执行
npm install dayjs -S
// 使用
import dayjs from 'dayjs'
  • 浏览器
<script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>
<script>
  dayjs().format()
</script>

日期格式化

常用的格式化占位符

标识示例描述
YY22年,两位数
YYYY2022年,四位数
M1-12月,从1开始
MM01-12月,两位数
D1-31
DD01-31日,两位数
H0-23小时
HH00-23小时,两位数
h1-12小时, 12 小时制
hh01-12小时, 12 小时制, 两位数
m0-59分钟
mm00-59分钟,两位数
s0-59
ss00-59秒,两位数
  • 格式化年月日: 'yyyy年mm月dd日'
// dayjs不传参默认是取当前时间
dayjs().format('YYYY年MM月DD日') // '2022年09月07日'
// 指定时间
dayjs(new Date()).format('YYYY年MM月DD日') // '2022年09月07日'
  • 格式化年月日: 'YYYY-MM-DD'
// dayjs不传参默认是取当前时间
dayjs().format('YYYY-MM-DD') // '2022-09-07'
// 指定时间
dayjs(new Date()).format('YYYY-MM-DD') // '2022-09-07'
  • 格式化时分秒:'hh:mm:ss'
dayjs().format('HH:mm:ss') // '10:06:05'

国际化

dayjs默认是使用英文en, 如果需要展示中文需进行配置

import dayjs from 'dayjs'
import 'dayjs/locale/zh-cn' // 导入本地化语言

dayjs.locale('zh-cn') // 使用本地化语言

取值/赋值

时间戳

// 获取当前时间的时间戳
dayjs().valueOf() // 1662531014567

年份

// 获取年份
dayjs().year() // 2022
// 设置年份
dayjs().year('2021') // 设置为2021年

月份

传入0到11的 number。 如果超出这个范围,它会进位到年份。

// 获取月份
dayjs().month() // 8
// 设置月份
dayjs().month(8) // 设置为9月

日期

接受1到31的数字。 如果超出这个范围,它会进位到月份。

// 获取日期
dayjs().date() // 7
// 设置日期
dayjs().date(1) // 设置为1号

星期(周日为一周的开始)

传入 number 从0(星期天)到6(星期六)。 如果超出这个范围,它会进位到其他周

// 获取星期
dayjs().day() // 3
// 设置星期
dayjs().day(0) // 设置为周日

ISO星期(周一为一周的开始)

使用本功能需先配置 IsoWeek 插件,才能正常运行

import dayjs from 'dayjs'
import IsoWeek from 'dayjs/plugin/isoWeek'
dayjs.extend(IsoWeek)
// 获取星期
dayjs().isoWeekday() // 3
// 设置星期
dayjs().isoWeekday(0) // 设置为周一

季度

此功能依赖 QuarterOfYear 插件

import dayjs from 'dayjs'
import QuarterOfYear from 'dayjs/plugin/quarterOfYear'
dayjs.extend(QuarterOfYear)
// 获取季度
dayjs('2022-04-01').quarter() // 2
// 设置季度
dayjs().quarter(2) // 设置为第二季度

常用操作

获取00:00:00时间

// 获取当前时间零点
dayjs().startOf('day').format('YYYY-MM-DD HH:mm:ss') // 2022-09-07 00:00:00
// 获取指定时间零点
dayjs('2022-08-23').startOf('day').format('YYYY-MM-DD HH:mm:ss') // 2022-08-23 00:00:00

获取23:59:59时间

// 获取当前时间23点
dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss') // 2022-09-07 23:59:59
// 获取指定时间23点
dayjs('2022-08-23').endOf('day').format('YYYY-MM-DD HH:mm:ss') // 2022-08-23 23:59:59

获取月初(1号)和月尾日期(31号)

// 获取指定日期的月初
dayjs('2022-09').startOf('month').format('YYYY-MM-DD') // '2022-09-01'
// 获取指定日期的月尾
dayjs('2022-09').endOf('month').format('YYYY-MM-DD') // '2022-09-30'

获取年初(xxx-01-01)和年尾日期(xxxx-12-31)

// 获取指定日期的年初
dayjs('2022').startOf('year').format('YYYY-MM-DD') // '2022-01-01'
// 获取指定日期的年尾
dayjs('2022').endOf('year').format('YYYY-MM-DD') // '2022-12-31'

获取当月天数

dayjs('2022-09').daysInMonth() // 30
dayjs('2022-08').daysInMonth() // 31

获取当年天数

/**
 * 获取当年天数
 * @param time 
 * @returns number
 */
export const getDayInYear = function(time: ConfigType = new Date()) {
    const year = dayjs(time).year()
    const months = new Array(12).fill(null).map((item, index) => index + 1)
    const days = months.reduce((prev, cur) => {
        let ym = year + '-' + cur
        let dayInMonth = dayjs(ym).daysInMonth()
        return prev + dayInMonth
    }, 0)
    return days
}

const year2022 = getDayInYear('2022') // 365
const year2020 = getDayInYear('2020') // 366

获取是一年中的第几周

此功能依赖 WeekOfYear 插件

import dayjs from 'dayjs'
import WeekOfYear from 'dayjs/plugin/weekOfYear'
dayjs.extend(WeekOfYear)

dayjs('2022-09-07').week() // 36

获取一年中的第几天

此功能依赖 dayOfYear 插件

import dayjs from 'dayjs'
import dayOfYear from 'dayjs/plugin/dayOfYear'
dayjs.extend(dayOfYear)

dayjs('2022-09-07').dayOfYear() // 250

判断是否是闰年

此功能依赖 isLeapYear 插件

import dayjs from 'dayjs'
import isLeapYear from 'dayjs/plugin/isLeapYear'
dayjs.extend(isLeapYear)

dayjs('2000-01-01').isLeapYear() // true

获取一天/月/年之前

import dayjs, { ManipulateType, ConfigType } from 'dayjs'
/**
 * 获取指定日期的前一天/月
 * @param {*} time 
 * @param {string} type 操作类型: 日:'day', 月: 'month'
 * @returns 时间戳
 */
export const prevTime = function(time: ConfigType = new Date(), type: ManipulateType ='day') {
    return dayjs(time).add(-1, type).valueOf()
}

prevTime(new Date(), 'day') // 一天之前的时间戳
prevTime(new Date(), 'month') // 一个月之前的时间戳
prevTime(new Date(), 'year') // 一年之前的时间戳

获取N天之前

import dayjs, { ConfigType } from 'dayjs'
/**
 * 计算前多少天或者往后多少天
 * @param {*} time 
 * @param {number} day 间隔的天数, eg: 1代表往后一天, -2: 代表往前2天
 * @returns 时间戳
 */
export const prevDays = function(time: ConfigType = new Date(), day:number) {
    return dayjs(time).add(day, 'day').valueOf()
}

prevDays(new Date(), -2)  // 往前两天
prevDays(new Date(), 2)  // 往后两天

获取N月之前

import dayjs, { ConfigType } from 'dayjs'
/**
 * 计算前多少月或者往后多少月
 * @param {*} time 
 * @param {number} month 间隔的月数, eg: 1代表往后一月, -2: 代表往前2月
 * @returns 时间戳
 */
export const prevMonths = function(time: ConfigType = new Date(), month:number) {
    return dayjs(time).add(month, 'month').valueOf()
}

prevMonths(new Date(), -2)  // 往前两月
prevMonths(new Date(), 2)  // 往后两月

近一周

import dayjs, { ConfigType } from 'dayjs'

// 格式化
export const format = function(time: ConfigType = new Date(),fmt = 'YYYY-MM-DD') {
    return dayjs(time).format(fmt)
}
/**
 * 获取近一周时间范围
 * @param {*} time 
 * @returns object
 * eg: time: 2022-09-02  result: {startTime: '2022-08-27', endTime: '2022-09-02'}
 */
export const recentWeek = function(time: ConfigType = new Date()) {
    let endTime = format(time, YMD)
    let startTime = format(dayjs(endTime).add(-6, 'day'), YMD)
    return {
        startTime, endTime
    }
}

recentWeek('2022-09-02') // {startTime: '2022-08-27', endTime: '2022-09-02'}

近一个月

import dayjs, { ConfigType } from 'dayjs'

// 格式化
export const format = function(time: ConfigType = new Date(),fmt = 'YYYY-MM-DD') {
    return dayjs(time).format(fmt)
}
/**
 * 获取近一个月时间范围
 * @param {*} time 
 * @returns object
 * eg:time: 2022-09-02  result: {startTime: '2022-08-02', endTime: '2022-09-02'}
 */
export const recentMonth = function(time: ConfigType = new Date()) {
    let endTime = format(time, YMD)
    // 往前推一个月 在加一天()
    let start = dayjs(endTime).subtract(1, 'month')
    let startTime = format(start, YMD)
    return {
        startTime, endTime
    }
}

recentMonth('2022-09-02') // {startTime: '2022-08-02', endTime: '2022-09-02'}

获取日历中一周的范围(周一 ~ 周日)

此功能依赖 IsoWeek 插件

import dayjs, { ConfigType } from 'dayjs'
import IsoWeek from 'dayjs/plugin/isoWeek'
dayjs.extend(IsoWeek)
/**
 * 获取指定日期在日历中一周的范围
 * @param {*} time 
 * @returns object
 * eg: time : 2022-09-02   result: {weekStart: '2022-08-29', weekEnd: '2022-09-04'}
 */
export const getWeekRange = function(time: ConfigType = new Date()) {
    let weekStart = dayjs(time).startOf('isoWeek').format(YMD)
    let weekEnd = dayjs(time).endOf('isoWeek').format(YMD)
    return {
        weekStart, weekEnd
    }
}
// 获取2022-09-02那一周的范围
getWeekRange('2022-09-02') // {weekStart: '2022-08-29', weekEnd: '2022-09-04'}

获取日历中一月的范围(1号 ~ 31号)

import dayjs, { ConfigType } from 'dayjs'
/**
 * 获取指定日期在日历中当月的范围
 * @param {*} time 
 * @returns object
 * eg: time : 2022-09-02   result: {monthStart: '2022-09-01', monthEnd: '2022-09-30'}
 */
export const getMonthRange = function(time: ConfigType = new Date()) {
    let monthStart = dayjs(time).startOf('month').format(YMD)
    let monthEnd = dayjs(time).endOf('month').format(YMD)
    return {
        monthStart, monthEnd
    }
}
// 获取2022-09-02那一月的范围
getMonthRange('2022-09-02') // {monthStart: '2022-09-01', monthEnd: '2022-09-30'}

时间差(相对当前时间)

此功能依赖 RelativeTime 插件

import dayjs, { ConfigType } from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime' // 相对时间
dayjs.extend(relativeTime)

/**
 * 返回现在到当前实例的相对时间
 * @param {*} time 
 * @returns string
 * eg: time: '2022-08-12' results: '22 天前'
 */
export const getRelativeTime = function(time: ConfigType) {
    return dayjs(time).fromNow()
}

getRelativeTime('2022-09-07 13:30:22') // 22 分钟前
getRelativeTime('2022-09-05 08:30:22') // 2 天前
getRelativeTime('2022-08-28 08:30:22') // 10 天前
getRelativeTime('2022-07-28 08:30:22') // 1 个月前
getRelativeTime('2021-01-28 08:30:22') // 2 年前

获取两个时间的时间差

import dayjs, { ManipulateType, ConfigType } from 'dayjs'

/**
 * 返回指定单位下两个日期时间之间的差异
 * @param {*} startTime 
 * @param {*} endTime 
 * @param {*} type 差异的类型: type: '' | 'day' | 'hour' | 'minute'
 * @returns number 默认返回毫秒数
 */
export const getTimeDiff = function(startTime: ConfigType, endTime: ConfigType, type: ManipulateType = 'millisecond') {
    let start = dayjs(startTime)
    let end = dayjs(endTime)
    if (type) {
        return Math.abs(start.diff(end, type))
    } else {
        return Math.abs(start.diff(end))
    }
}

// 获取时间差:毫秒数
getTimeDiff('2022-09-05 08:30:22', new Date()) // 192110824
// 获取时间差:秒数
getTimeDiff('2022-09-05 08:30:22', new Date(), 'second') // 192110
// 获取时间差:分钟数
getTimeDiff('2022-09-05 08:30:22', new Date(), 'minute') // 3201
// 获取时间差:小时数
getTimeDiff('2022-09-05 08:30:22', new Date(), 'hour') // 53
// 获取时间差:天数
getTimeDiff('2022-09-05 08:30:22', new Date(), 'day') // 2