date-format.js 3.7 KB

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