date-format.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // yyyy-MM-dd hh:mm:ss.SSS 所有支持的类型
  2. function pad(str, length = 2) {
  3. str += ''
  4. while (str.length < length) {
  5. str = '0' + str
  6. }
  7. return str.slice(-length)
  8. }
  9. const parser = {
  10. yyyy: (dateObj) => {
  11. return pad(dateObj.year, 4)
  12. },
  13. yy: (dateObj) => {
  14. return pad(dateObj.year)
  15. },
  16. MM: (dateObj) => {
  17. return pad(dateObj.month)
  18. },
  19. M: (dateObj) => {
  20. return dateObj.month
  21. },
  22. dd: (dateObj) => {
  23. return pad(dateObj.day)
  24. },
  25. d: (dateObj) => {
  26. return dateObj.day
  27. },
  28. hh: (dateObj) => {
  29. return pad(dateObj.hour)
  30. },
  31. h: (dateObj) => {
  32. return dateObj.hour
  33. },
  34. mm: (dateObj) => {
  35. return pad(dateObj.minute)
  36. },
  37. m: (dateObj) => {
  38. return dateObj.minute
  39. },
  40. ss: (dateObj) => {
  41. return pad(dateObj.second)
  42. },
  43. s: (dateObj) => {
  44. return dateObj.second
  45. },
  46. SSS: (dateObj) => {
  47. return pad(dateObj.millisecond, 3)
  48. },
  49. S: (dateObj) => {
  50. return dateObj.millisecond
  51. },
  52. }
  53. export function formatDate(date, format = 'yyyy/MM/dd hh:mm:ss') {
  54. date = date instanceof Date ? date : new Date(date)
  55. const dateObj = {
  56. year: date.getFullYear(),
  57. month: date.getMonth() + 1,
  58. day: date.getDate(),
  59. hour: date.getHours(),
  60. minute: date.getMinutes(),
  61. second: date.getSeconds(),
  62. millisecond: date.getMilliseconds()
  63. }
  64. const tokenRegExp = /yyyy|yy|MM|M|dd|d|hh|h|mm|m|ss|s|SSS|SS|S/
  65. let flag = true
  66. let result = format
  67. while (flag) {
  68. flag = false
  69. result = result.replace(tokenRegExp, function(matched) {
  70. flag = true
  71. return parser[matched](dateObj)
  72. })
  73. }
  74. return result
  75. }
  76. export function friendlyDate(time, {
  77. locale = 'zh',
  78. threshold = [60000, 3600000],
  79. format = 'yyyy/MM/dd hh:mm:ss'
  80. }) {
  81. const localeText = {
  82. zh: {
  83. year: '年',
  84. month: '月',
  85. day: '天',
  86. hour: '小时',
  87. minute: '分钟',
  88. second: '秒',
  89. ago: '前',
  90. later: '后',
  91. justNow: '刚刚',
  92. soon: '马上',
  93. template: '{num}{unit}{suffix}'
  94. },
  95. en: {
  96. year: 'year',
  97. month: 'month',
  98. day: 'day',
  99. hour: 'hour',
  100. minute: 'minute',
  101. second: 'second',
  102. ago: 'ago',
  103. later: 'later',
  104. justNow: 'just now',
  105. soon: 'soon',
  106. template: '{num} {unit} {suffix}'
  107. }
  108. }
  109. const text = localeText[locale] || localeText.zh
  110. let date = new Date(time)
  111. let ms = date.getTime() - Date.now()
  112. let absMs = Math.abs(ms)
  113. if (absMs < threshold[0]) {
  114. return ms < 0 ? text.justNow : text.soon
  115. }
  116. if (absMs >= threshold[1]) {
  117. return formatDate(date, format)
  118. }
  119. let num
  120. let unit
  121. let suffix = text.later
  122. if (ms < 0) {
  123. suffix = text.ago
  124. ms = -ms
  125. }
  126. const seconds = Math.floor((ms) / 1000)
  127. const minutes = Math.floor(seconds / 60)
  128. const hours = Math.floor(minutes / 60)
  129. const days = Math.floor(hours / 24)
  130. const months = Math.floor(days / 30)
  131. const years = Math.floor(months / 12)
  132. switch (true) {
  133. case years > 0:
  134. num = years
  135. unit = text.year
  136. break
  137. case months > 0:
  138. num = months
  139. unit = text.month
  140. break
  141. case days > 0:
  142. num = days
  143. unit = text.day
  144. break
  145. case hours > 0:
  146. num = hours
  147. unit = text.hour
  148. break
  149. case minutes > 0:
  150. num = minutes
  151. unit = text.minute
  152. break
  153. default:
  154. num = seconds
  155. unit = text.second
  156. break
  157. }
  158. if (locale === 'en') {
  159. if (num === 1) {
  160. num = 'a'
  161. } else {
  162. unit += 's'
  163. }
  164. }
  165. return text.template.replace(/{\s*num\s*}/g, num + '').replace(/{\s*unit\s*}/g, unit).replace(/{\s*suffix\s*}/g,
  166. suffix)
  167. }