date.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /**
  2. * 对Date的扩展,将 Date 转化为指定格式的String。
  3. *
  4. * 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
  5. * 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)。
  6. *
  7. * 【示例】:
  8. * formatDate(new Date(), 'yyyy-MM-dd hh:mm:ss.S') ==> 2006-07-02 08:09:04.423
  9. * formatDate(new Date(), 'yyyy-M-d h:m:s.S') ==> 2006-7-2 8:9:4.18
  10. * formatDate(new Date(), 'hh:mm:ss.S') ==> 08:09:04.423
  11. */
  12. export function formatDate(date, fmt) {
  13. const o = {
  14. 'M+': date.getMonth() + 1, //月份
  15. 'd+': date.getDate(), //日
  16. 'h+': date.getHours(), //小时
  17. 'm+': date.getMinutes(), //分
  18. 's+': date.getSeconds(), //秒
  19. 'q+': Math.floor((date.getMonth() + 3) / 3), //季度
  20. S: date.getMilliseconds(), //毫秒
  21. }
  22. if (/(y+)/.test(fmt)) {
  23. fmt = fmt.replace(
  24. RegExp.$1,
  25. (date.getFullYear() + '').substr(4 - RegExp.$1.length)
  26. )
  27. }
  28. for (let k in o) {
  29. if (new RegExp('(' + k + ')').test(fmt)) {
  30. let value =
  31. RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)
  32. fmt = fmt.replace(RegExp.$1, value)
  33. }
  34. }
  35. return fmt
  36. }
  37. /**
  38. * 仿照微信中的消息时间显示逻辑,将时间戳(单位:毫秒)转换为友好的显示格式.
  39. *
  40. * 1)7天之内的日期显示逻辑是:今天、昨天(-1d)、前天(-2d)、星期?(只显示总计7天之内的星期数,即<=-4d);
  41. * 2)7天之外(即>7天)的逻辑:直接显示完整日期时间。
  42. *
  43. * @param {[long]} timestamp 时间戳(单位:毫秒),形如:1550789954260
  44. * @param {boolean} mustIncludeTime true表示输出的格式里一定会包含“时间:分钟”
  45. * ,否则不包含(参考微信,不包含时分的情况,用于首页“消息”中显示时)
  46. *
  47. * @return {string} 输出格式形如:“刚刚”、“10:30”、“昨天 12:04”、“前天 20:51”、“星期二”、“2019/2/21 12:09”等形式
  48. */
  49. export function formatDateShort(timestamp, mustIncludeTime) {
  50. // 当前时间
  51. let currentDate = new Date()
  52. // 目标判断时间
  53. let srcDate = new Date(parseInt(timestamp))
  54. let currentYear = currentDate.getFullYear()
  55. let currentMonth = currentDate.getMonth() + 1
  56. let currentDateD = currentDate.getDate()
  57. let srcYear = srcDate.getFullYear()
  58. let srcMonth = srcDate.getMonth() + 1
  59. let srcDateD = srcDate.getDate()
  60. let ret = ''
  61. // 要额外显示的时间分钟
  62. let timeExtraStr = mustIncludeTime ? ' ' + formatDate(srcDate, 'hh:mm') : ''
  63. // 当年
  64. if (currentYear == srcYear) {
  65. let currentTimestamp = currentDate.getTime()
  66. let srcTimestamp = timestamp
  67. // 相差时间(单位:毫秒)
  68. let deltaTime = currentTimestamp - srcTimestamp
  69. // 当天(月份和日期一致才是)
  70. if (currentMonth == srcMonth && currentDateD == srcDateD) {
  71. // 时间相差60秒以内
  72. if (deltaTime < 60 * 1000) ret = '刚刚'
  73. // 否则当天其它时间段的,直接显示“时:分”的形式
  74. else ret = formatDate(srcDate, 'hh:mm')
  75. }
  76. // 当年 && 当天之外的时间(即昨天及以前的时间)
  77. else {
  78. // 昨天(以“现在”的时候为基准-1天)
  79. let yesterdayDate = new Date()
  80. yesterdayDate.setDate(yesterdayDate.getDate() - 1)
  81. // 前天(以“现在”的时候为基准-2天)
  82. let beforeYesterdayDate = new Date()
  83. beforeYesterdayDate.setDate(beforeYesterdayDate.getDate() - 2)
  84. // 用目标日期的“月”和“天”跟上方计算出来的“昨天”进行比较,是最为准确的(如果用时间戳差值
  85. // 的形式,是不准确的,比如:现在时刻是2019年02月22日1:00、而srcDate是2019年02月21日23:00,
  86. // 这两者间只相差2小时,直接用“deltaTime/(3600 * 1000)” > 24小时来判断是否昨天,就完全是扯蛋的逻辑了)
  87. if (
  88. srcMonth == yesterdayDate.getMonth() + 1 &&
  89. srcDateD == yesterdayDate.getDate()
  90. )
  91. ret = '昨天' + timeExtraStr
  92. // -1d
  93. // “前天”判断逻辑同上
  94. else if (
  95. srcMonth == beforeYesterdayDate.getMonth() + 1 &&
  96. srcDateD == beforeYesterdayDate.getDate()
  97. )
  98. ret = '前天' + timeExtraStr
  99. // -2d
  100. else {
  101. // 跟当前时间相差的小时数
  102. let deltaHour = deltaTime / (3600 * 1000)
  103. // 如果小于或等 7*24小时就显示星期几
  104. if (deltaHour <= 7 * 24) {
  105. let weekday = new Array(7)
  106. weekday[0] = '星期日'
  107. weekday[1] = '星期一'
  108. weekday[2] = '星期二'
  109. weekday[3] = '星期三'
  110. weekday[4] = '星期四'
  111. weekday[5] = '星期五'
  112. weekday[6] = '星期六'
  113. // 取出当前是星期几
  114. let weedayDesc = weekday[srcDate.getDay()]
  115. ret = weedayDesc + timeExtraStr
  116. }
  117. // 否则直接显示完整日期时间
  118. else {
  119. ret = formatDate(srcDate, 'yyyy/M/d') + timeExtraStr
  120. }
  121. }
  122. }
  123. }
  124. // 往年
  125. else {
  126. ret = formatDate(srcDate, 'yyyy/M/d') + timeExtraStr
  127. }
  128. return ret
  129. }