tt-mp
Version:
一套组件化、可复用、易扩展的头条小程序 UI 组件库
98 lines (92 loc) • 3.31 kB
JavaScript
/**
* 解析时间
*/
export const parse = (date) => {
if (date instanceof Date) return date
if (!isNaN(date) || /^\d+$/.test(date)) return new Date(parseInt(date, 10))
let s = date.trim()
s = s.replace(/\.\d+/, '') // remove milliseconds
s = s.replace(/-/, '/').replace(/-/, '/')
s = s.replace(/T/, ' ').replace(/Z/, ' UTC')
s = s.replace(/([\+\-]\d\d)\:?(\d\d)/, ' $1$2') // -04:00 -> -0400
s = s.replace(/([\+\-]\d\d)$/, ' $100') // +09 -> +0900
return new Date(s)
}
/**
* 计算月份差
*/
export const monthDiff = (startMonth, endMonth) => {
const start = parse(startMonth)
const end = parse(endMonth)
return (
(start.getFullYear() - end.getFullYear()) * 12 +
start.getMonth() -
end.getMonth()
)
}
/**
* 计算时间差
*/
export const diff = (date, nowDate, unit) => {
const start = parse(date)
const end = nowDate ? parse(nowDate) : new Date()
const output = end.getTime() - start.getTime()
return (
(unit === 'second' && output / 1000) ||
(unit === 'minute' && output / 1000 / 60) ||
(unit === 'hour' && output / 1000 / 60 / 60) ||
(unit === 'day' && output / 1000 / 60 / 60 / 24) ||
(unit === 'week' && output / 1000 / 60 / 60 / 24 / 7) ||
(unit === 'month' && monthDiff(start, end)) ||
(unit === 'quarter' && monthDiff(start, end) / 3) ||
(unit === 'year' && monthDiff(start, end) / 12) ||
output
)
}
/**
* default language
*/
const defaults = {
second: ['刚刚', '片刻后'],
seconds: ['%d 秒前', '%d 秒后'],
minute: ['大约 1 分钟前', '大约 1 分钟后'],
minutes: ['%d 分钟前', '%d 分钟后'],
hour: ['大约 1 小时前', '大约 1 小时后'],
hours: ['%d 小时前', '%d 小时后'],
day: ['1 天前', '1 天后'],
days: ['%d 天前', '%d 天后'],
month: ['大约 1 个月前', '大约 1 个月后'],
months: ['%d 月前', '%d 月后'],
year: ['大约 1 年前', '大约 1 年后'],
years: ['%d 年前', '%d 年后'],
}
/**
* format timeago
* @param {Number} diff 时间差
* @param {Object} opts 配置参数
* @return {String} 文本内容
*/
export const format = (diff, opts) => {
const options = Object.assign({}, defaults, opts)
const agoin = diff < 0 ? 1 : 0 // timein or timeago
const seconds = Math.abs(diff) / 1000
const minutes = seconds / 60
const hours = minutes / 60
const days = hours / 24
const years = days / 365
const substitute = (string, number) => string.replace(/%d/i, number)
return (
(seconds < 10 && substitute(options.second[agoin], parseInt(seconds))) ||
(seconds < 45 && substitute(options.seconds[agoin], parseInt(seconds))) ||
(seconds < 90 && substitute(options.minute[agoin], 1)) ||
(minutes < 45 && substitute(options.minutes[agoin], parseInt(minutes))) ||
(minutes < 90 && substitute(options.hour[agoin], 1)) ||
(hours < 24 && substitute(options.hours[agoin], parseInt(hours))) ||
(hours < 42 && substitute(options.day[agoin], 1)) ||
(days < 30 && substitute(options.days[agoin], parseInt(days))) ||
(days < 45 && substitute(options.month[agoin], 1)) ||
(days < 365 && substitute(options.months[agoin], parseInt(days / 30))) ||
(years < 1.5 && substitute(options.year[agoin], 1)) ||
substitute(options.years[agoin], parseInt(years))
)
}