formatTime.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. import dayjs from 'dayjs'
  2. import quarter from 'dayjs/plugin/quarterOfYear'
  3. dayjs.extend(quarter)
  4. import type { TableColumnCtx } from 'element-plus'
  5. /**
  6. * 日期快捷选项适用于 el-date-picker
  7. */
  8. export const rangeShortcuts = [
  9. {
  10. text: '今天',
  11. value: () => {
  12. const today = dayjs()
  13. return [today.startOf('day').toDate(), today.endOf('day').toDate()]
  14. }
  15. },
  16. {
  17. text: '昨天',
  18. value: () => {
  19. const yesterday = dayjs().subtract(1, 'day')
  20. return [yesterday.startOf('day').toDate(), yesterday.endOf('day').toDate()]
  21. }
  22. },
  23. {
  24. text: '本周',
  25. value: () => {
  26. return [dayjs().subtract(6, 'day').startOf('day').toDate(), dayjs().endOf('day').toDate()]
  27. }
  28. },
  29. {
  30. text: '上周',
  31. value: () => {
  32. return [
  33. dayjs().subtract(13, 'day').startOf('day').toDate(),
  34. dayjs().subtract(7, 'day').endOf('day').toDate()
  35. ]
  36. }
  37. },
  38. {
  39. text: '本月',
  40. value: () => {
  41. return [dayjs().startOf('month').toDate(), dayjs().endOf('month').toDate()]
  42. }
  43. },
  44. {
  45. text: '上月',
  46. value: () => {
  47. const lastMonth = dayjs().subtract(1, 'month')
  48. return [lastMonth.startOf('month').toDate(), lastMonth.endOf('month').toDate()]
  49. }
  50. },
  51. {
  52. text: '本季度',
  53. value: () => {
  54. return [dayjs().startOf('quarter').toDate(), dayjs().endOf('quarter').toDate()]
  55. }
  56. },
  57. {
  58. text: '上季度',
  59. value: () => {
  60. const lastQuarter = dayjs().subtract(1, 'quarter')
  61. return [lastQuarter.startOf('quarter').toDate(), lastQuarter.endOf('quarter').toDate()]
  62. }
  63. },
  64. {
  65. text: '今年',
  66. value: () => {
  67. return [dayjs().startOf('year').toDate(), dayjs().endOf('year').toDate()]
  68. }
  69. },
  70. {
  71. text: '去年',
  72. value: () => {
  73. const lastYear = dayjs().subtract(1, 'year')
  74. return [lastYear.startOf('year').toDate(), lastYear.endOf('year').toDate()]
  75. }
  76. },
  77. {
  78. text: '最近7天',
  79. value: () => {
  80. return [dayjs().subtract(6, 'day').toDate(), dayjs().toDate()]
  81. }
  82. },
  83. {
  84. text: '最近30天',
  85. value: () => {
  86. return [dayjs().subtract(29, 'day').toDate(), dayjs().toDate()]
  87. }
  88. },
  89. {
  90. text: '最近90天',
  91. value: () => {
  92. return [dayjs().subtract(89, 'day').toDate(), dayjs().toDate()]
  93. }
  94. },
  95. {
  96. text: '最近一年',
  97. value: () => {
  98. return [dayjs().subtract(1, 'year').toDate(), dayjs().toDate()]
  99. }
  100. }
  101. ]
  102. export const defaultShortcuts = [
  103. {
  104. text: '今天',
  105. value: () => {
  106. return new Date()
  107. }
  108. },
  109. {
  110. text: '昨天',
  111. value: () => {
  112. const date = new Date()
  113. date.setTime(date.getTime() - 3600 * 1000 * 24)
  114. return [date, date]
  115. }
  116. },
  117. {
  118. text: '最近七天',
  119. value: () => {
  120. const date = new Date()
  121. date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
  122. return [date, new Date()]
  123. }
  124. },
  125. {
  126. text: '最近 30 天',
  127. value: () => {
  128. const date = new Date()
  129. date.setTime(date.getTime() - 3600 * 1000 * 24 * 30)
  130. return [date, new Date()]
  131. }
  132. },
  133. {
  134. text: '本月',
  135. value: () => {
  136. const date = new Date()
  137. date.setDate(1) // 设置为当前月的第一天
  138. return [date, new Date()]
  139. }
  140. },
  141. {
  142. text: '今年',
  143. value: () => {
  144. const date = new Date()
  145. return [new Date(`${date.getFullYear()}-01-01`), date]
  146. }
  147. }
  148. ]
  149. /**
  150. * 时间日期转换
  151. * @param date 当前时间,new Date() 格式
  152. * @param format 需要转换的时间格式字符串
  153. * @description format 字符串随意,如 `YYYY-MM、YYYY-MM-DD`
  154. * @description format 季度:"YYYY-MM-DD HH:mm:ss QQQQ"
  155. * @description format 星期:"YYYY-MM-DD HH:mm:ss WWW"
  156. * @description format 几周:"YYYY-MM-DD HH:mm:ss ZZZ"
  157. * @description format 季度 + 星期 + 几周:"YYYY-MM-DD HH:mm:ss WWW QQQQ ZZZ"
  158. * @returns 返回拼接后的时间字符串
  159. */
  160. export function formatDate(date: Date, format?: string): string {
  161. // 日期不存在,则返回空
  162. if (!date) {
  163. return ''
  164. }
  165. // 日期存在,则进行格式化
  166. return date ? dayjs(date).format(format ?? 'YYYY-MM-DD HH:mm:ss') : ''
  167. }
  168. /**
  169. * 获取当前的日期+时间
  170. */
  171. export function getNowDateTime() {
  172. return dayjs()
  173. }
  174. /**
  175. * 获取当前日期是第几周
  176. * @param dateTime 当前传入的日期值
  177. * @returns 返回第几周数字值
  178. */
  179. export function getWeek(dateTime: Date): number {
  180. const temptTime = new Date(dateTime.getTime())
  181. // 周几
  182. const weekday = temptTime.getDay() || 7
  183. // 周1+5天=周六
  184. temptTime.setDate(temptTime.getDate() - weekday + 1 + 5)
  185. let firstDay = new Date(temptTime.getFullYear(), 0, 1)
  186. const dayOfWeek = firstDay.getDay()
  187. let spendDay = 1
  188. if (dayOfWeek != 0) spendDay = 7 - dayOfWeek + 1
  189. firstDay = new Date(temptTime.getFullYear(), 0, 1 + spendDay)
  190. const d = Math.ceil((temptTime.valueOf() - firstDay.valueOf()) / 86400000)
  191. return Math.ceil(d / 7)
  192. }
  193. /**
  194. * 将时间转换为 `几秒前`、`几分钟前`、`几小时前`、`几天前`
  195. * @param param 当前时间,new Date() 格式或者字符串时间格式
  196. * @param format 需要转换的时间格式字符串
  197. * @description param 10秒: 10 * 1000
  198. * @description param 1分: 60 * 1000
  199. * @description param 1小时: 60 * 60 * 1000
  200. * @description param 24小时:60 * 60 * 24 * 1000
  201. * @description param 3天: 60 * 60* 24 * 1000 * 3
  202. * @returns 返回拼接后的时间字符串
  203. */
  204. export function formatPast(param: string | Date, format = 'YYYY-MM-DD HH:mm:ss'): string {
  205. // 传入格式处理、存储转换值
  206. let t: any, s: number
  207. // 获取js 时间戳
  208. let time: number = new Date().getTime()
  209. // 是否是对象
  210. typeof param === 'string' || 'object' ? (t = new Date(param).getTime()) : (t = param)
  211. // 当前时间戳 - 传入时间戳
  212. time = Number.parseInt(`${time - t}`)
  213. if (time < 10000) {
  214. // 10秒内
  215. return '刚刚'
  216. } else if (time < 60000 && time >= 10000) {
  217. // 超过10秒少于1分钟内
  218. s = Math.floor(time / 1000)
  219. return `${s}秒前`
  220. } else if (time < 3600000 && time >= 60000) {
  221. // 超过1分钟少于1小时
  222. s = Math.floor(time / 60000)
  223. return `${s}分钟前`
  224. } else if (time < 86400000 && time >= 3600000) {
  225. // 超过1小时少于24小时
  226. s = Math.floor(time / 3600000)
  227. return `${s}小时前`
  228. } else if (time < 259200000 && time >= 86400000) {
  229. // 超过1天少于3天内
  230. s = Math.floor(time / 86400000)
  231. return `${s}天前`
  232. } else {
  233. // 超过3天
  234. const date = typeof param === 'string' || 'object' ? new Date(param) : param
  235. return formatDate(date, format)
  236. }
  237. }
  238. /**
  239. * 时间问候语
  240. * @param param 当前时间,new Date() 格式
  241. * @description param 调用 `formatAxis(new Date())` 输出 `上午好`
  242. * @returns 返回拼接后的时间字符串
  243. */
  244. export function formatAxis(param: Date): string {
  245. const hour: number = new Date(param).getHours()
  246. if (hour < 6) return '凌晨好'
  247. else if (hour < 9) return '早上好'
  248. else if (hour < 12) return '上午好'
  249. else if (hour < 14) return '中午好'
  250. else if (hour < 17) return '下午好'
  251. else if (hour < 19) return '傍晚好'
  252. else if (hour < 22) return '晚上好'
  253. else return '夜里好'
  254. }
  255. /**
  256. * 将毫秒,转换成时间字符串。例如说,xx 分钟
  257. *
  258. * @param ms 毫秒
  259. * @returns {string} 字符串
  260. */
  261. export function formatPast2(ms: number): string {
  262. const day = Math.floor(ms / (24 * 60 * 60 * 1000))
  263. const hour = Math.floor(ms / (60 * 60 * 1000) - day * 24)
  264. const minute = Math.floor(ms / (60 * 1000) - day * 24 * 60 - hour * 60)
  265. const second = Math.floor(ms / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60)
  266. if (day > 0) {
  267. return day + ' 天' + hour + ' 小时 ' + minute + ' 分钟'
  268. }
  269. if (hour > 0) {
  270. return hour + ' 小时 ' + minute + ' 分钟'
  271. }
  272. if (minute > 0) {
  273. return minute + ' 分钟'
  274. }
  275. if (second > 0) {
  276. return second + ' 秒'
  277. } else {
  278. return 0 + ' 秒'
  279. }
  280. }
  281. /**
  282. * element plus 的时间 Formatter 实现,使用 YYYY-MM-DD HH:mm:ss 格式
  283. *
  284. * @param row 行数据
  285. * @param column 字段
  286. * @param cellValue 字段值
  287. */
  288. export function dateFormatter(
  289. _row: any,
  290. _column: TableColumnCtx<any> | null,
  291. cellValue: any
  292. ): string {
  293. return cellValue ? formatDate(cellValue) : ''
  294. }
  295. /**
  296. * element plus 的时间 Formatter 实现,使用 YYYY-MM-DD 格式
  297. *
  298. * @param row 行数据
  299. * @param column 字段
  300. * @param cellValue 字段值
  301. */
  302. export function dateFormatter2(
  303. _row: any,
  304. _column: TableColumnCtx<any> | null,
  305. cellValue: any
  306. ): string {
  307. return cellValue ? formatDate(cellValue, 'YYYY-MM-DD') : ''
  308. }
  309. /**
  310. * 设置起始日期,时间为00:00:00
  311. * @param param 传入日期
  312. * @returns 带时间00:00:00的日期
  313. */
  314. export function beginOfDay(param: Date): Date {
  315. return new Date(param.getFullYear(), param.getMonth(), param.getDate(), 0, 0, 0)
  316. }
  317. /**
  318. * 设置结束日期,时间为23:59:59
  319. * @param param 传入日期
  320. * @returns 带时间23:59:59的日期
  321. */
  322. export function endOfDay(param: Date): Date {
  323. return new Date(param.getFullYear(), param.getMonth(), param.getDate(), 23, 59, 59)
  324. }
  325. /**
  326. * 计算两个日期间隔天数
  327. * @param param1 日期1
  328. * @param param2 日期2
  329. */
  330. export function betweenDay(param1: Date, param2: Date): number {
  331. param1 = convertDate(param1)
  332. param2 = convertDate(param2)
  333. // 计算差值
  334. return Math.floor((param2.getTime() - param1.getTime()) / (24 * 3600 * 1000))
  335. }
  336. /**
  337. * 日期计算
  338. * @param param1 日期
  339. * @param param2 添加的时间
  340. */
  341. export function addTime(param1: Date, param2: number): Date {
  342. param1 = convertDate(param1)
  343. return new Date(param1.getTime() + param2)
  344. }
  345. /**
  346. * 日期转换
  347. * @param param 日期
  348. */
  349. export function convertDate(param: Date | string): Date {
  350. if (typeof param === 'string') {
  351. return new Date(param)
  352. }
  353. return param
  354. }
  355. /**
  356. * 指定的两个日期, 是否为同一天
  357. * @param a 日期 A
  358. * @param b 日期 B
  359. */
  360. export function isSameDay(a: dayjs.ConfigType, b: dayjs.ConfigType): boolean {
  361. if (!a || !b) return false
  362. const aa = dayjs(a)
  363. const bb = dayjs(b)
  364. return aa.year() == bb.year() && aa.month() == bb.month() && aa.day() == bb.day()
  365. }
  366. /**
  367. * 获取一天的开始时间、截止时间
  368. * @param date 日期
  369. * @param days 天数
  370. */
  371. export function getDayRange(
  372. date: dayjs.ConfigType,
  373. days: number
  374. ): [dayjs.ConfigType, dayjs.ConfigType] {
  375. const day = dayjs(date).add(days, 'd')
  376. return getDateRange(day, day)
  377. }
  378. /**
  379. * 获取最近7天的开始时间、截止时间
  380. */
  381. export function getLast7Days(): [dayjs.ConfigType, dayjs.ConfigType] {
  382. const lastWeekDay = dayjs().subtract(7, 'd')
  383. const yesterday = dayjs().subtract(1, 'd')
  384. return getDateRange(lastWeekDay, yesterday)
  385. }
  386. /**
  387. * 获取最近30天的开始时间、截止时间
  388. */
  389. export function getLast30Days(): [dayjs.ConfigType, dayjs.ConfigType] {
  390. const lastMonthDay = dayjs().subtract(30, 'd')
  391. const yesterday = dayjs().subtract(1, 'd')
  392. return getDateRange(lastMonthDay, yesterday)
  393. }
  394. /**
  395. * 获取最近1年的开始时间、截止时间
  396. */
  397. export function getLast1Year(): [dayjs.ConfigType, dayjs.ConfigType] {
  398. const lastYearDay = dayjs().subtract(1, 'y')
  399. const yesterday = dayjs().subtract(1, 'd')
  400. return getDateRange(lastYearDay, yesterday)
  401. }
  402. /**
  403. * 获取指定日期的开始时间、截止时间
  404. * @param beginDate 开始日期
  405. * @param endDate 截止日期
  406. */
  407. export function getDateRange(
  408. beginDate: dayjs.ConfigType,
  409. endDate: dayjs.ConfigType
  410. ): [string, string] {
  411. return [
  412. dayjs(beginDate).startOf('d').format('YYYY-MM-DD HH:mm:ss'),
  413. dayjs(endDate).endOf('d').format('YYYY-MM-DD HH:mm:ss')
  414. ]
  415. }