|
| 1 | +/** |
| 2 | + * Date Utilities |
| 3 | + * 处理时间的工具类 |
| 4 | + * @typedef {Date|string|number} DateLike |
| 5 | + */ |
| 6 | + |
| 7 | +/** |
| 8 | + * UTC 时间转化为祖鲁时间 |
| 9 | + * 避免使用 new Date() 时产生时区时差 |
| 10 | + * |
| 11 | + * @author mutoe <mutoe@foxmail.com> |
| 12 | + * @param {DateLike} date |
| 13 | + * @returns {string} |
| 14 | + * @example const date = "2018-12-24 10:06:48" |
| 15 | + * toZuluTimezone(date) // -> "2018-12-24T10:06:48Z" |
| 16 | + */ |
| 17 | +export function toZuluTimezone (date) { |
| 18 | + const matcher = /^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})$/ |
| 19 | + if (!matcher.test(date)) return date |
| 20 | + return date.replace(matcher, '$1T$2Z') |
| 21 | +} |
| 22 | + |
| 23 | +/** |
| 24 | + * 判断目标日期是否是昨天 |
| 25 | + * |
| 26 | + * @author mutoe <mutoe@foxmail.com> |
| 27 | + * @export |
| 28 | + * @param {DateLike} target |
| 29 | + * @returns {boolean} |
| 30 | + */ |
| 31 | +export function isYesterday (target) { |
| 32 | + const date = new Date() |
| 33 | + const today = +new Date(date.getFullYear(), date.getMonth(), date.getDate()) // 今日凌晨 |
| 34 | + const yesterday = +new Date(today - 1000 * 24 * 3600) // 昨日凌晨 |
| 35 | + target = +new Date(target) |
| 36 | + return target < today && target > yesterday |
| 37 | +} |
| 38 | + |
| 39 | +/** |
| 40 | + * 获取目标时间到当前时间的时间差 |
| 41 | + * |
| 42 | + * @author mutoe <mutoe@foxmail.com> |
| 43 | + * @param {DateLike} target |
| 44 | + * @returns {string} |
| 45 | + */ |
| 46 | +export function fromNow (target) { |
| 47 | + const zulu = toZuluTimezone(target) |
| 48 | + const date = new Date(zulu) |
| 49 | + const offset = (new Date() - new Date(date)) / 1000 |
| 50 | + if (Number.isNaN(offset)) { |
| 51 | + console.error('时间解析错误:', target) // eslint-disable-line no-console |
| 52 | + return String(target) |
| 53 | + } |
| 54 | + let relative = offset |
| 55 | + |
| 56 | + // 今天 |
| 57 | + if (relative < 60) return '1分钟内' |
| 58 | + relative = Math.floor(relative / 60) // min |
| 59 | + if (relative < 60) return `${relative}分钟前` |
| 60 | + relative = Math.floor(relative / 60) // hour |
| 61 | + if (relative < 24) return `${relative}小时前` |
| 62 | + |
| 63 | + // 超过 1 天 |
| 64 | + const timeString = date.toTimeString().substr(0, 5) |
| 65 | + relative = Math.floor(relative / 24) // day |
| 66 | + if (isYesterday(date)) return `昨天 ${timeString}` |
| 67 | + if (relative < 9) return `${relative}天前` |
| 68 | + |
| 69 | + // 超过 9 天 |
| 70 | + const dateString = `${date.getMonth()}-${date.getDate()}` |
| 71 | + return dateString |
| 72 | +} |
0 commit comments