index.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /**
  2. * 将输入的任意对象转换成 Date,如果装换失败将返回当前时间
  3. * @param {any} datetime 需要被格式化的时间
  4. * @return {Date} 转换好的 Date
  5. */
  6. function getDateObject(datetime) {
  7. let t = datetime instanceof Date ? datetime : new Date(datetime);
  8. if (!t.getDate()) {
  9. t = new Date();
  10. }
  11. return t;
  12. }
  13. /**
  14. * 格式化时间
  15. * @param {Date} datetime 需要被格式化的时间
  16. * @param {string} formatStr 格式化字符串,默认为 'YYYY-MM-DD HH:mm:ss'
  17. * @return {string} 格式化后的时间字符串
  18. */
  19. export function format(datetime, formatStr) {
  20. let t = getDateObject(datetime);
  21. let hours, o, i = 0;
  22. formatStr = formatStr || 'YYYY-MM-DD HH:mm:ss';
  23. hours = t.getHours();
  24. o = [
  25. ['M+', t.getMonth() + 1],
  26. ['D+', t.getDate()],
  27. // H 24小时制
  28. ['H+', hours],
  29. // h 12小时制
  30. ['h+', hours > 12 ? hours - 12 : hours],
  31. ['m+', t.getMinutes()],
  32. ['s+', t.getSeconds()],
  33. ];
  34. // 替换 Y
  35. if (/(Y+)/.test(formatStr)) {
  36. formatStr = formatStr.replace(RegExp.$1, (t.getFullYear() + '').substr(4 - RegExp.$1.length));
  37. }
  38. // 替换 M, D, H, h, m, s
  39. for (; i < o.length; i++) {
  40. if (new RegExp('(' + o[i][0] + ')').test(formatStr)) {
  41. formatStr = formatStr.replace(RegExp.$1, RegExp.$1.length === 1 ? o[i][1] : ('00' + o[i][1]).substr(('' + o[i][1]).length));
  42. }
  43. }
  44. // 替换 a/A 为 am, pm
  45. return formatStr.replace(/a/ig, hours > 11 ? 'pm' : 'am');
  46. }
  47. /**
  48. * CONST and VAR for .fromNow
  49. */
  50. // 预设语言:英语
  51. const LOCALE_EN = {
  52. future: 'in %s',
  53. past: '%s ago',
  54. s: 'a few seconds',
  55. mm: '%s minutes',
  56. hh: '%s hours',
  57. dd: '%s days',
  58. MM: '%s months',
  59. yy: '%s years'
  60. };
  61. // 预设语言:简体中文
  62. const LOCALE_ZH_CN = {
  63. future: '%s内',
  64. past: '%s前',
  65. s: '几秒',
  66. mm: '%s分钟',
  67. hh: '%s小时',
  68. dd: '%s天',
  69. MM: '%s月',
  70. yy: '%s年'
  71. };
  72. // 当前本地化语言对象
  73. let _curentLocale;
  74. /**
  75. * 修改本地化语言
  76. * @param {string|Object} string: 预设语言 `zh-cn` 或 `en`;Object: 自定义 locate 对象
  77. */
  78. export function locate(arg) {
  79. let newLocale, prop;
  80. if (typeof arg === 'string') {
  81. newLocale = arg === 'zh-cn' ? LOCALE_ZH_CN : LOCALE_EN;
  82. } else {
  83. newLocale = arg;
  84. }
  85. if (!_curentLocale) {
  86. _curentLocale = {};
  87. }
  88. for (prop in newLocale) {
  89. if (newLocale.hasOwnProperty(prop) && typeof newLocale[prop] === 'string') {
  90. _curentLocale[prop] = newLocale[prop];
  91. }
  92. }
  93. }
  94. /**
  95. * CONST for .fromNow
  96. */
  97. // 各计算区间
  98. const DET_STD = [
  99. [ 'yy', 31536e6 ], // 1000 * 60 * 60 * 24 * 365 一年月按 365 天算
  100. [ 'MM', 2592e6 ], // 1000 * 60 * 60 * 24 * 30 一个月按 30 天算
  101. [ 'dd', 864e5 ], // 1000 * 60 * 60 * 24
  102. [ 'hh', 36e5 ], // 1000 * 60 * 60
  103. [ 'mm', 6e4 ], // 1000 * 60
  104. [ 's', 0 ], // 只要大于等于 0 都是秒
  105. ];
  106. /**
  107. * 计算给出时间和当前时间的时间距离
  108. * @param {Date} datetime 需要计算的时间
  109. * @return {string} 时间距离
  110. */
  111. export function fromNow(datetime) {
  112. if (!_curentLocale) {
  113. // 初始化本地化语言为 en
  114. locate('');
  115. }
  116. let det = +new Date() - (+getDateObject(datetime));
  117. let format, str, i = 0, detDef, detDefVal;
  118. if (det < 0) {
  119. format = _curentLocale.future;
  120. det = -det;
  121. } else {
  122. format = _curentLocale.past;
  123. }
  124. for (; i < DET_STD.length; i++) {
  125. detDef = DET_STD[i];
  126. detDefVal = detDef[1];
  127. if (det >= detDefVal) {
  128. str = _curentLocale[detDef[0]].replace('%s', parseInt(det/detDefVal, 0) || 1);
  129. break;
  130. }
  131. }
  132. return format.replace('%s', str);
  133. }