bindbox-game/.trae/documents/修复 Windows 打包后时区错误(unknown time zone Asia_Shanghai).md
邹方成 8141a47690
Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 39s
feat(称号系统): 新增称号管理功能与抽奖效果集成
- 新增系统称号模板与效果配置表及相关CRUD接口
- 实现用户称号分配与抽奖效果应用逻辑
- 优化抽奖接口支持用户ID参数以应用称号效果
- 新增称号管理前端页面与分配功能
- 修复Windows时区错误与JSON字段初始化问题
- 移除无用管理接口代码并更新文档说明
2025-11-16 11:37:40 +08:00

2.4 KiB
Raw Blame History

问题定位

  • 触发点在 internal/pkg/timeutil/timeutil.go:13-22time.LoadLocation("Asia/Shanghai")init 中执行,失败则 panic,并将 time.Local 设为中国时区。
  • 在 Windows 无系统 IANA tzdata、且以 CGO_ENABLED=0 交叉编译的静态二进制中,time 包找不到 Asia/Shanghai,导致启动时报错。

解决方案(按优先级)

  • 方案A推荐嵌入 tzdata 到二进制
    • 在应用入口 main.go 增加空导入:_ "time/tzdata",使 time 包使用内嵌 IANA 数据库。
    • 或在打包时添加构建标签:-tags timetzdata(效果等同),无需改代码。
  • 方案B无代码变更随程序分发 zoneinfo.zip
    • 复制 $GOROOT/lib/time/zoneinfo.zip 到可执行文件同目录,运行前设置环境变量 ZONEINFO 指向该文件,例如:set ZONEINFO=%CD%\zoneinfo.zip
  • 方案C防御补充去除 panic 并提供容错
    • timeutil 初始化失败时,回退到固定东八区:time.FixedZone("CST", 8*3600),并设置 time.Local,避免启动失败。

打包命令更新

  • 将 README 中 Windows 打包命令更新为:
    • CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags "-s -w" -tags timetzdata -trimpath -o build/bindbox.exe .
  • 若采用方案Bbuild 目录放置 zoneinfo.zip,并在启动脚本/说明中加入 set ZONEINFO=%~dp0zoneinfo.zip

验证计划

  • 本地编译并运行单测:覆盖 internal/pkg/timeutil 的格式化与解析函数,确认 Asia/Shanghai 可加载且不崩溃。
  • 人工验证:在 Windows 主机上执行 bindbox.exe 并访问 http://127.0.0.1:9991/system/health,字段 time 正常返回中国时区时间(参考 internal/pkg/core/core.go:418-441timeutil.CSTLayoutString())。

将实施的具体改动

  • 若选A
    • main.go 增加 _ "time/tzdata" 导入。
    • 更新 README 的 Windows 构建命令,加入 -tags timetzdata
  • 若选C可选增强
    • 修改 internal/pkg/timeutil/timeutil.go,失败时不 panic,改为固定时区回退并日志记录。

回滚与兼容

  • 方案A仅增加约 ~800KB 体积,无行为回滚风险。
  • 方案C为防御性修改兼容现有逻辑若需恢复原严格行为可还原为 panic

请确认采用的方案推荐选A可附加选C增强健壮性。确认后我将按上述步骤实施并提交更改、完成打包与验证。