date-format.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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. // 这都n年了iOS依然不认识2020-12-12,需要转换为2020/12/12
  54. function getDate(time) {
  55. if (time instanceof Date) {
  56. return time
  57. }
  58. switch (typeof time) {
  59. case 'string':
  60. return new Date(time.replace(/-/g, '/'))
  61. default:
  62. return new Date(time)
  63. }
  64. }
  65. export function formatDate(date, format = 'yyyy/MM/dd hh:mm:ss') {
  66. if (!date && date !== 0) {
  67. return '-'
  68. }
  69. date = getDate(date)
  70. const dateObj = {
  71. year: date.getFullYear(),
  72. month: date.getMonth() + 1,
  73. day: date.getDate(),
  74. hour: date.getHours(),
  75. minute: date.getMinutes(),
  76. second: date.getSeconds(),
  77. millisecond: date.getMilliseconds()
  78. }
  79. const tokenRegExp = /yyyy|yy|MM|M|dd|d|hh|h|mm|m|ss|s|SSS|SS|S/
  80. let flag = true
  81. let result = format
  82. while (flag) {
  83. flag = false
  84. result = result.replace(tokenRegExp, function(matched) {
  85. flag = true
  86. return parser[matched](dateObj)
  87. })
  88. }
  89. return result
  90. }
  91. export function friendlyDate(time, {
  92. locale = 'zh',
  93. threshold = [60000, 3600000],
  94. format = 'yyyy/MM/dd hh:mm:ss'
  95. }) {
  96. if (!time && time !== 0) {
  97. return '-'
  98. }
  99. const localeText = {
  100. zh: {
  101. year: '年',
  102. month: '月',
  103. day: '天',
  104. hour: '小时',
  105. minute: '分钟',
  106. second: '秒',
  107. ago: '前',
  108. later: '后',
  109. justNow: '刚刚',
  110. soon: '马上',
  111. template: '{num}{unit}{suffix}'
  112. },
  113. en: {
  114. year: 'year',
  115. month: 'month',
  116. day: 'day',
  117. hour: 'hour',
  118. minute: 'minute',
  119. second: 'second',
  120. ago: 'ago',
  121. later: 'later',
  122. justNow: 'just now',
  123. soon: 'soon',
  124. template: '{num} {unit} {suffix}'
  125. }
  126. }
  127. const text = localeText[locale] || localeText.zh
  128. let date = getDate(time)
  129. let ms = date.getTime() - Date.now()
  130. let absMs = Math.abs(ms)
  131. if (absMs < threshold[0]) {
  132. return ms < 0 ? text.justNow : text.soon
  133. }
  134. if (absMs >= threshold[1]) {
  135. return formatDate(date, format)
  136. }
  137. let num
  138. let unit
  139. let suffix = text.later
  140. if (ms < 0) {
  141. suffix = text.ago
  142. ms = -ms
  143. }
  144. const seconds = Math.floor((ms) / 1000)
  145. const minutes = Math.floor(seconds / 60)
  146. const hours = Math.floor(minutes / 60)
  147. const days = Math.floor(hours / 24)
  148. const months = Math.floor(days / 30)
  149. const years = Math.floor(months / 12)
  150. switch (true) {
  151. case years > 0:
  152. num = years
  153. unit = text.year
  154. break
  155. case months > 0:
  156. num = months
  157. unit = text.month
  158. break
  159. case days > 0:
  160. num = days
  161. unit = text.day
  162. break
  163. case hours > 0:
  164. num = hours
  165. unit = text.hour
  166. break
  167. case minutes > 0:
  168. num = minutes
  169. unit = text.minute
  170. break
  171. default:
  172. num = seconds
  173. unit = text.second
  174. break
  175. }
  176. if (locale === 'en') {
  177. if (num === 1) {
  178. num = 'a'
  179. } else {
  180. unit += 's'
  181. }
  182. }
  183. return text.template.replace(/{\s*num\s*}/g, num + '').replace(/{\s*unit\s*}/g, unit).replace(/{\s*suffix\s*}/g,
  184. suffix)
  185. }