refactor(时区): 常量收进契约、SQL 统一走 localTime,去掉会话时区与 TZ 兜底
Some checks failed
Deploy / deploy (push) Has been cancelled
Some checks failed
Deploy / deploy (push) Has been cancelled
- TIME_ZONE / TIME_ZONE_OFFSET_MINUTES 移到 packages/contract/src/time.ts,
前后端共用一份,不再各写一遍靠注释对齐。
- apps/api/src/time.ts 新增 localTime(列),替换散落 7 处的
`at time zone ${TIME_ZONE_SQL}`;ac-trend 的 where 复用同一个 year 表达式。
- /problems/:displayId/yearly-ac 漏写了时区、按 UTC 切年,被会话时区兜底掩盖;
改为按东八区切(只影响每年 12-31 北京 0–8 点的提交归年)。
- 删掉数据库连接的 TimeZone 和 Dockerfile 的 TZ:正确代码不依赖它们,
它们只会在线上掩盖漏写处、让 dev 与线上答案不同。
- time.ts:calendarDayYearsAgo/pad 并入 shiftMonthsByCalendar,startOfCalendarDay
并入 todayStart,localWeekday 改用 getUTCDay,删掉历史叙述注释。
- 前端 zonedParts 改为固定偏移 + getUTC*(与后端、日期选择器同一写法),
去掉 Intl formatToParts;10 万次 299ms → 11ms。zonedYear 去掉按浏览器时区的兜底。
- 两份 CLAUDE.md 同步;n-date-picker 那条过时说明改成现用法。
验证:新旧「近两年起点」21359 个时刻 0 差异、localWeekday 0 差异、
前端固定偏移与 Intl 在 America/New_York 下 47821 个时刻 0 差异;
localTime 在 select/group by/where 复用可用;fix-achievement-hours 预演仍为 148 / 60。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1d8B3f4SXJwDvUY625eQd
This commit is contained in:
@@ -136,15 +136,13 @@ return contract("GET /problems/:id", problemDetailSchema, value)
|
||||
(比如时区没设对的机房机器、或在外地的老师)从别的时区打开,同一张提交记录表就会
|
||||
显示成另一个时间,和榜单、统计、成就里的日期对不上。
|
||||
|
||||
锚点在后端 `../api/src/time.ts`(`Asia/Shanghai`),前端的 `DISPLAY_TIME_ZONE`
|
||||
必须和它一致。实现用 `Intl` 的 IANA 时区而不是自己加 8 小时,`timeZone` 选项
|
||||
Chrome 24+ 就支持,不影响机房老 Chrome。
|
||||
时区常量在契约 `@oj2/contract` 的 `TIME_ZONE_OFFSET_MINUTES`,和后端 `time.ts` 共用。
|
||||
实现是「平移固定偏移 + 读 `getUTC*`」,不用 `Intl` 的时区选项:东八区没有夏令时,
|
||||
纯算术在表格里逐格调用也不费事,老 Chrome 上结果也一致。
|
||||
|
||||
**唯一还没跟上的是 `n-date-picker`**(`admin/contest/detail.vue`、
|
||||
`admin/problemset/edit.vue`):Naive 的日期选择器按浏览器本地时区渲染,没有
|
||||
`timezone` 属性。它在绝对值上往返正确(选的是什么时刻就是什么时刻),只是在非东八区
|
||||
的机器上「输入框里显示的时间」和「列表里显示的时间」会差一个时区。要修得在
|
||||
value ↔ 显示值之间做偏移换算,属于独立改动。
|
||||
**`n-date-picker` 要平移**(`admin/contest/detail.vue`、`admin/problemset/edit.vue`):
|
||||
Naive 的日期选择器按浏览器本地时区渲染、没有 `timezone` 属性,所以绑定值走
|
||||
`toPickerValue()`,取回来走 `fromPickerValue()`。显示时间不要用这对函数。
|
||||
|
||||
### Key Utilities
|
||||
|
||||
|
||||
Reference in New Issue
Block a user