| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- function normalizeTimestamp(ts) {
- let value = parseInt(ts, 10)
- if (!value) value = Date.now()
- if (String(value).length === 10) value *= 1000
- return value
- }
- function padUnit(value, width) {
- const text = String(value)
- return width > 1 ? text.padStart(width, '0') : text
- }
- export function formatTimestamp(ts, pattern = 'yyyy-mm-dd') {
- const date = new Date(normalizeTimestamp(ts))
- const tokens = {
- 'y+': String(date.getFullYear()),
- 'm+': String(date.getMonth() + 1),
- 'd+': String(date.getDate()),
- 'h+': String(date.getHours()),
- 'M+': String(date.getMinutes()),
- 's+': String(date.getSeconds())
- }
- let output = pattern
- for (const token of Object.keys(tokens)) {
- const match = new RegExp(`(${token})`).exec(output)
- if (!match) continue
- const width = match[1].length
- output = output.replace(match[1], padUnit(tokens[token], width))
- }
- return output
- }
- export function createRelativeTimeFormatter(i18n) {
- const translate = (key, fallback) => {
- try {
- return i18n ? i18n.t(key) : fallback
- } catch (_) {
- return fallback
- }
- }
- return { translate }
- }
- export function socialRelativeTime(ts, pattern = 'yyyy-mm-dd', i18n) {
- const { translate } = createRelativeTimeFormatter(i18n)
- const seconds = Math.floor((Date.now() - normalizeTimestamp(ts)) / 1000)
- if (seconds < 300) return translate('find.just-now', '刚刚')
- if (seconds < 3600) return `${Math.floor(seconds / 60)}${translate('find.minutes-ago', '分钟前')}`
- if (seconds < 86400) return `${Math.floor(seconds / 3600)}${translate('find.hours-ago', '小时前')}`
- if (seconds < 2592000) return `${Math.floor(seconds / 86400)}${translate('find.days-ago', '天前')}`
- if (pattern === false) {
- if (seconds < 365 * 86400) {
- return `${Math.floor(seconds / (86400 * 30))}${translate('find.months-ago', '个月前')}`
- }
- return `${Math.floor(seconds / (86400 * 365))}${translate('find.years-ago', '年前')}`
- }
- return formatTimestamp(ts, pattern)
- }
- export function chatBubbleTime(ts, i18n) {
- const { translate } = createRelativeTimeFormatter(i18n)
- const seconds = Math.floor((Date.now() - normalizeTimestamp(ts)) / 1000)
- if (seconds < 86400) return formatTimestamp(ts, 'hh:MM')
- const weekdays = (() => {
- try {
- const list = i18n.t('find.weekdays', { returnObjects: true })
- if (Array.isArray(list)) return list
- } catch (_) {}
- return ['日', '一', '二', '三', '四', '五', '六']
- })()
- const locale = i18n ? i18n.locale : 'zh-Hans'
- const chineseStyle = locale.startsWith('zh') || locale === 'ja'
- const clock = formatTimestamp(ts, 'hh:MM')
- const when = new Date(normalizeTimestamp(ts))
- const dayGap = new Date().getDate() - when.getDate()
- if (seconds < 86400 * 7) {
- if (dayGap === 1) return `${translate('find.yesterday', '昨天')} ${clock}`
- if (dayGap === 2) return `${translate('find.dayBeforeYesterday', '前天')} ${clock}`
- const weekLabel = weekdays[when.getDay()]
- return chineseStyle
- ? `${translate('find.week', '星期')}${weekLabel} ${clock}`
- : `${weekLabel} ${clock}`
- }
- if (seconds >= 86400 * 7) return formatTimestamp(ts, 'mm-dd hh:MM')
- return formatTimestamp(ts, 'yyyy-mm-dd hh:MM')
- }
|