You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
5.0 KiB
218 lines
5.0 KiB
/** |
|
* Day.js 日期工具函数 |
|
* 统一管理日期格式化和处理 |
|
*/ |
|
|
|
import dayjs from 'dayjs'; |
|
import relativeTime from 'dayjs/plugin/relativeTime'; |
|
import calendar from 'dayjs/plugin/calendar'; |
|
import duration from 'dayjs/plugin/duration'; |
|
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore'; |
|
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter'; |
|
import 'dayjs/locale/zh-cn'; |
|
|
|
// 扩展插件 |
|
dayjs.extend(relativeTime); |
|
dayjs.extend(calendar); |
|
dayjs.extend(duration); |
|
dayjs.extend(isSameOrBefore); |
|
dayjs.extend(isSameOrAfter); |
|
|
|
// 设置默认语言为中文 |
|
dayjs.locale('zh-cn'); |
|
|
|
/** |
|
* 日期格式常量 |
|
*/ |
|
export const DATE_FORMATS = { |
|
FULL: 'YYYY-MM-DD HH:mm:ss', |
|
DATE: 'YYYY-MM-DD', |
|
TIME: 'HH:mm:ss', |
|
DATE_TIME: 'YYYY-MM-DD HH:mm', |
|
MONTH_DAY: 'MM-DD', |
|
HOUR_MINUTE: 'HH:mm', |
|
YEAR_MONTH: 'YYYY-MM', |
|
CHINESE_DATE: 'YYYY年MM月DD日', |
|
CHINESE_FULL: 'YYYY年MM月DD日 HH:mm:ss', |
|
} as const; |
|
|
|
/** |
|
* 格式化日期 |
|
* @param date 日期(Date、时间戳或字符串) |
|
* @param format 格式(默认:YYYY-MM-DD HH:mm:ss) |
|
*/ |
|
export const formatDate = ( |
|
date: Date | string | number, |
|
format: string = DATE_FORMATS.FULL |
|
): string => { |
|
return dayjs(date).format(format); |
|
}; |
|
|
|
/** |
|
* 格式化为相对时间(如:3分钟前、2小时前) |
|
*/ |
|
export const formatRelativeTime = (date: Date | string | number): string => { |
|
return dayjs(date).fromNow(); |
|
}; |
|
|
|
/** |
|
* 格式化为日历时间(如:今天、昨天、上周) |
|
*/ |
|
export const formatCalendarTime = (date: Date | string | number): string => { |
|
return dayjs(date).calendar(null, { |
|
sameDay: '[今天] HH:mm', |
|
lastDay: '[昨天] HH:mm', |
|
lastWeek: 'MM-DD HH:mm', |
|
sameElse: 'YYYY-MM-DD HH:mm', |
|
}); |
|
}; |
|
|
|
/** |
|
* 格式化聊天时间 |
|
* 今天:显示时间 |
|
* 昨天:显示"昨天 + 时间" |
|
* 本年:显示"月-日 时间" |
|
* 往年:显示"年-月-日" |
|
*/ |
|
export const formatChatTime = (timestamp: number | string | Date): string => { |
|
const date = dayjs(timestamp); |
|
const now = dayjs(); |
|
|
|
if (date.isSame(now, 'day')) { |
|
// 今天 |
|
return date.format('HH:mm'); |
|
} else if (date.isSame(now.subtract(1, 'day'), 'day')) { |
|
// 昨天 |
|
return '昨天 ' + date.format('HH:mm'); |
|
} else if (date.isSame(now, 'year')) { |
|
// 本年 |
|
return date.format('MM-DD HH:mm'); |
|
} else { |
|
// 往年 |
|
return date.format('YYYY-MM-DD'); |
|
} |
|
}; |
|
|
|
/** |
|
* 获取时间差(返回对象) |
|
*/ |
|
export const getTimeDiff = ( |
|
startDate: Date | string | number, |
|
endDate: Date | string | number = new Date() |
|
) => { |
|
const start = dayjs(startDate); |
|
const end = dayjs(endDate); |
|
const diff = end.diff(start); |
|
|
|
const duration = dayjs.duration(diff); |
|
|
|
return { |
|
years: duration.years(), |
|
months: duration.months(), |
|
days: duration.days(), |
|
hours: duration.hours(), |
|
minutes: duration.minutes(), |
|
seconds: duration.seconds(), |
|
milliseconds: duration.milliseconds(), |
|
totalDays: Math.floor(duration.asDays()), |
|
totalHours: Math.floor(duration.asHours()), |
|
totalMinutes: Math.floor(duration.asMinutes()), |
|
totalSeconds: Math.floor(duration.asSeconds()), |
|
}; |
|
}; |
|
|
|
/** |
|
* 判断是否是今天 |
|
*/ |
|
export const isToday = (date: Date | string | number): boolean => { |
|
return dayjs(date).isSame(dayjs(), 'day'); |
|
}; |
|
|
|
/** |
|
* 判断是否是昨天 |
|
*/ |
|
export const isYesterday = (date: Date | string | number): boolean => { |
|
return dayjs(date).isSame(dayjs().subtract(1, 'day'), 'day'); |
|
}; |
|
|
|
/** |
|
* 判断是否是本周 |
|
*/ |
|
export const isThisWeek = (date: Date | string | number): boolean => { |
|
return dayjs(date).isSame(dayjs(), 'week'); |
|
}; |
|
|
|
/** |
|
* 判断是否是本月 |
|
*/ |
|
export const isThisMonth = (date: Date | string | number): boolean => { |
|
return dayjs(date).isSame(dayjs(), 'month'); |
|
}; |
|
|
|
/** |
|
* 判断是否是本年 |
|
*/ |
|
export const isThisYear = (date: Date | string | number): boolean => { |
|
return dayjs(date).isSame(dayjs(), 'year'); |
|
}; |
|
|
|
/** |
|
* 获取日期范围的开始和结束 |
|
*/ |
|
export const getDateRange = (type: 'day' | 'week' | 'month' | 'year') => { |
|
const now = dayjs(); |
|
return { |
|
start: now.startOf(type).toDate(), |
|
end: now.endOf(type).toDate(), |
|
}; |
|
}; |
|
|
|
/** |
|
* 添加时间 |
|
*/ |
|
export const addTime = ( |
|
date: Date | string | number, |
|
amount: number, |
|
unit: dayjs.ManipulateType |
|
): Date => { |
|
return dayjs(date).add(amount, unit).toDate(); |
|
}; |
|
|
|
/** |
|
* 减去时间 |
|
*/ |
|
export const subtractTime = ( |
|
date: Date | string | number, |
|
amount: number, |
|
unit: dayjs.ManipulateType |
|
): Date => { |
|
return dayjs(date).subtract(amount, unit).toDate(); |
|
}; |
|
|
|
/** |
|
* 判断日期是否在范围内 |
|
*/ |
|
export const isBetween = ( |
|
date: Date | string | number, |
|
startDate: Date | string | number, |
|
endDate: Date | string | number |
|
): boolean => { |
|
const target = dayjs(date); |
|
return target.isAfter(startDate) && target.isBefore(endDate); |
|
}; |
|
|
|
/** |
|
* 获取当前时间戳(毫秒) |
|
*/ |
|
export const now = (): number => { |
|
return dayjs().valueOf(); |
|
}; |
|
|
|
/** |
|
* 获取当前时间戳(秒) |
|
*/ |
|
export const nowInSeconds = (): number => { |
|
return Math.floor(dayjs().valueOf() / 1000); |
|
}; |
|
|
|
export default dayjs;
|
|
|