38 lines
1.3 KiB
TypeScript
38 lines
1.3 KiB
TypeScript
/**
|
|
* 后台统一按北京时间展示。
|
|
*
|
|
* 后端返回的是 ISO 字符串(UTC,带 Z),直接切片会显示成 UTC——
|
|
* 中午 13:23 会显示成 05:23。所有时间展示都走这里。不要再用 slice。
|
|
*/
|
|
const TIME_ZONE = 'Asia/Shanghai';
|
|
|
|
function partsOf(value: unknown) {
|
|
const date = new Date(String(value));
|
|
if (Number.isNaN(date.getTime())) return null;
|
|
const parts = new Intl.DateTimeFormat('zh-CN', {
|
|
timeZone: TIME_ZONE,
|
|
year: 'numeric',
|
|
month: '2-digit',
|
|
day: '2-digit',
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
hourCycle: 'h23',
|
|
}).formatToParts(date);
|
|
const pick = (type: string) => parts.find((p) => p.type === type)?.value ?? '';
|
|
return { y: pick('year'), m: pick('month'), d: pick('day'), h: pick('hour'), mi: pick('minute') };
|
|
}
|
|
|
|
/** ISO → 2026-09-30 13:23 */
|
|
export function formatDateTime(value: unknown): string {
|
|
if (value === null || value === undefined || value === '') return '—';
|
|
const p = partsOf(value);
|
|
return p ? `${p.y}-${p.m}-${p.d} ${p.h}:${p.mi}` : String(value).slice(0, 16).replace('T', ' ');
|
|
}
|
|
|
|
/** ISO → 2026-09-30 */
|
|
export function formatDate(value: unknown): string {
|
|
if (value === null || value === undefined || value === '') return '—';
|
|
const p = partsOf(value);
|
|
return p ? `${p.y}-${p.m}-${p.d}` : String(value).slice(0, 10);
|
|
}
|