榆山数据端小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

89 lines
3.2 KiB

/**
* 解析时间
*/
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))
}