From cfe8d19da916008e4a00ca3ded175bbec81a722b Mon Sep 17 00:00:00 2001 From: XuqmGroup Date: Thu, 21 May 2026 16:49:55 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=AB=AF=20UTC=20LocalDateTime=20=E5=9C=A8=E6=B5=8F=E8=A7=88?= =?UTF-8?q?=E5=99=A8=E4=B8=AD=E7=9A=84=E8=A7=A3=E6=9E=90=E5=81=8F=E5=B7=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Jackson 配置 time-zone: UTC,LocalDateTime 序列化为不含时区后缀的 ISO 字符串(如 "2026-05-21T14:30:00")。浏览器将此类字符串视为本地 时间,导致非中国时区或非 UTC+8 环境出现 8 小时偏差。 修复:formatTime 对无时区后缀的 ISO 字符串补充 'Z',确保按 UTC 解析 后再转换为北京时间。 Co-Authored-By: Claude Sonnet 4.6 --- ops-platform/src/utils/date.ts | 9 ++++++++- tenant-platform/src/utils/date.ts | 12 +++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/ops-platform/src/utils/date.ts b/ops-platform/src/utils/date.ts index f0f02ed..2fda186 100644 --- a/ops-platform/src/utils/date.ts +++ b/ops-platform/src/utils/date.ts @@ -1,7 +1,14 @@ const TZ = 'Asia/Shanghai' +function toUTC(value: string): string { + return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(value) && !/[Z+\-]\d*$/.test(value) + ? value + 'Z' + : value +} + export function formatTime(value: string | number | null | undefined): string { if (value === null || value === undefined || value === '') return '-' - const date = new Date(value as string | number) + const input = typeof value === 'string' ? toUTC(value) : value + const date = new Date(input) return Number.isNaN(date.getTime()) ? '-' : date.toLocaleString('zh-CN', { timeZone: TZ }) } diff --git a/tenant-platform/src/utils/date.ts b/tenant-platform/src/utils/date.ts index f0f02ed..9d98f5c 100644 --- a/tenant-platform/src/utils/date.ts +++ b/tenant-platform/src/utils/date.ts @@ -1,7 +1,17 @@ const TZ = 'Asia/Shanghai' +// Backend serializes LocalDateTime without timezone (Jackson time-zone: UTC). +// Bare ISO strings like "2026-05-21T14:30:00" are treated as local time by browsers, +// so we append 'Z' to force UTC parsing before converting to Beijing time. +function toUTC(value: string): string { + return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(value) && !/[Z+\-]\d*$/.test(value) + ? value + 'Z' + : value +} + export function formatTime(value: string | number | null | undefined): string { if (value === null || value === undefined || value === '') return '-' - const date = new Date(value as string | number) + const input = typeof value === 'string' ? toUTC(value) : value + const date = new Date(input) return Number.isNaN(date.getTime()) ? '-' : date.toLocaleString('zh-CN', { timeZone: TZ }) }