在开发Web应用时,时间的准确显示至关重要,尤其是在需要展示用户交互时间(如评论、发帖)的场景。最近,我在一个Next.js博客项目中遇到了一个典型的时间显示问题: 本地开发环境下的评论时间显示正常(例如“15小时前”),但部署到服务器后却显示为“7小时前” 。这篇博客将详细记录我从发现问题、分析原因到最终解决的全过程,希望能为遇到类似问题的朋友提供一份参考。
一、问题的初现:诡异的8小时时差
问题的现象非常明确:
- 本地(Windows) :一条评论,显示为“15小时前”,完全符合预期。
- 服务器(Linux) :同样的评论,刷新后显示为“7小时前”。
我的第一反应是服务器的时区设置不正确。
二、初步尝试:在前端进行时区转换
既然问题与时区有关,我首先想到在前端处理时间格式化时进行强制的时区转换。项目中使用了 dayjs 库来处理时间。我的想法是:无论数据库返回什么时间,都先将其视作UTC时间,然后转换为用户的本地时间。想着如果全部统一使用UTC时间的话,这样不就统一了吗,当我修改完项目后,部署到服务器时,又发现诡异8小时时差。
此时就感觉到他们时区还是不一致,我通过 timedatectl 命令,试着查看一下 Linux 服务端的时区到底是什么。
当看到返回的结果,我发现 CST 的时区是符合我们当前的时间的,而 UTC 的时区却是减少8个小时,所以之前在我前端把时间处理成UTC时间时,就少了8个小时,这时候我们问题显而易见了。
三、UTC 和 CST 时区
1、基于定义
时区 | 全称 | 基准 |
UTC | 协调世界时 | 全球标准时间,原子钟校准 |
CST | 中国标准时间 | UTC+8(东八区) |
2、时间偏移量
-
UTC 是基准时间(偏移量为 ±0)。
-
CST 比 UTC 快8小时(即
CST = UTC + 8小时
)。
3. 实际应用场景
UTC 使用场景
- 全球科学、航空、计算机网络(如日志时间戳)。
- 国际服务器默认时间(避免时区混淆)。
- 例如:Linux 系统日志、Docker 容器时间、数据库 TIMESTAMP 字段。
CST 使用场景
- 中国境内所有官方和民用时间(包括台湾、香港、澳门)。
- Windows/macOS 系统本地化设置时显示为 北京时间。
得出结论是,CST是适合我们中国的时间显示,所以服务器的显示CST时区是正确的,且中国的 CST 永远比 UTC 快8小时
四、使用CST统一时区
通过上面例子,我们已经知道使用 UTC 是没办法来做为国内时区的,所以我们要使用CST来统一这个时区,至于如何统一呢,刚开始我是在页面中来统一时区
import utc from "dayjs/plugin/utc";
dayjs.extend(utc);
但是这样,如果涉及到多个地方要修改的话就比较头大,所以想了一下,能否从源头处理这个时区的问题,答案当然是有的,可以从连接mysql连接处,即
import mysql, { type Pool } from 'mysql2/promise'; // 使用 ES 模块导入方式
const dbPool: Pool = mysql.createPool({
// ...
timezone: '+08:00', // 设置数据库连接时区为CST(中国标准时间)
});
export default dbPool;
因为CST 永远比 UTC 快8小时,所以我们UTC要统一为CST,就是需要加8个小时,这样不管理线上和线下都统一CST时区。
发表评论
全部评论 (0)