date-format.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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 === '-') {
  103. return time
  104. }
  105. if (!time && time !== 0) {
  106. return ''
  107. }
  108. const localeText = {
  109. zh: {
  110. year: '年',
  111. month: '月',
  112. day: '天',
  113. hour: '小时',
  114. minute: '分钟',
  115. second: '秒',
  116. ago: '前',
  117. later: '后',
  118. justNow: '刚刚',
  119. soon: '马上',
  120. template: '{num}{unit}{suffix}'
  121. },
  122. en: {
  123. year: 'year',
  124. month: 'month',
  125. day: 'day',
  126. hour: 'hour',
  127. minute: 'minute',
  128. second: 'second',
  129. ago: 'ago',
  130. later: 'later',
  131. justNow: 'just now',
  132. soon: 'soon',
  133. template: '{num} {unit} {suffix}'
  134. }
  135. }
  136. const text = localeText[locale] || localeText.zh
  137. let date = getDate(time)
  138. let ms = date.getTime() - Date.now()
  139. let absMs = Math.abs(ms)
  140. if (absMs < threshold[0]) {
  141. return ms < 0 ? text.justNow : text.soon
  142. }
  143. if (absMs >= threshold[1]) {
  144. return formatDate(date, format)
  145. }
  146. let num
  147. let unit
  148. let suffix = text.later
  149. if (ms < 0) {
  150. suffix = text.ago
  151. ms = -ms
  152. }
  153. const seconds = Math.floor((ms) / 1000)
  154. const minutes = Math.floor(seconds / 60)
  155. const hours = Math.floor(minutes / 60)
  156. const days = Math.floor(hours / 24)
  157. const months = Math.floor(days / 30)
  158. const years = Math.floor(months / 12)
  159. switch (true) {
  160. case years > 0:
  161. num = years
  162. unit = text.year
  163. break
  164. case months > 0:
  165. num = months
  166. unit = text.month
  167. break
  168. case days > 0:
  169. num = days
  170. unit = text.day
  171. break
  172. case hours > 0:
  173. num = hours
  174. unit = text.hour
  175. break
  176. case minutes > 0:
  177. num = minutes
  178. unit = text.minute
  179. break
  180. default:
  181. num = seconds
  182. unit = text.second
  183. break
  184. }
  185. if (locale === 'en') {
  186. if (num === 1) {
  187. num = 'a'
  188. } else {
  189. unit += 's'
  190. }
  191. }
  192. return text.template.replace(/{\s*num\s*}/g, num + '').replace(/{\s*unit\s*}/g, unit).replace(/{\s*suffix\s*}/g,
  193. suffix)
  194. }