const UTC_DATE_FMT: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false, timeZone: 'UTC', } /** Backend unix nanoseconds (UTC+0) → localized date string with UTC suffix. */ export function formatUnixNano(ns: number | undefined | null): string | null { if (!ns || ns <= 0) return null const ms = Math.floor(ns / 1_000_000) const date = new Date(ms) if (Number.isNaN(date.getTime())) return null return `${date.toLocaleString('zh-TW', UTC_DATE_FMT)} UTC` } /** Threads / API posted_at (ISO or parseable string) → date label. */ export function formatPostedAt(raw: string | undefined | null): string | null { const value = raw?.trim() if (!value) return null const parsed = new Date(value) if (!Number.isNaN(parsed.getTime())) { return parsed.toLocaleString('zh-TW', UTC_DATE_FMT) + ' UTC' } if (/^\d{4}[-/]/.test(value)) return value return value } /** Scan post publish time. Do not fall back to crawl入库 time. */ export function formatScanPostDate(post: { posted_at?: string }): string | null { return formatPostedAt(post.posted_at) }