
Sequelize 默认使用 UTC 时区连接 PostgreSQL,而服务器或数据库实际运行在本地时区(如 GMT+1),导致 CURRENT_TIME 与 NOW() 返回值在 JavaScript 层被错误解析,引发时间逻辑错误。需显式配置 timezone 选项以对齐数据库时区。
sequelize 默认使用 utc 时区连接 postgresql,而服务器或数据库实际运行在本地时区(如 gmt+1),导致 `current_time` 与 `now()` 返回值在 javascript 层被错误解析,引发时间逻辑错误。需显式配置 `timezone` 选项以对齐数据库时区。
在使用 Sequelize 连接 PostgreSQL 时,你可能会遇到一个隐蔽但影响深远的问题:数据库返回的时间值在 Node.js 应用中显示为错误的时区偏移。例如,你的服务器和 PostgreSQL 均配置为 GMT+1(即 Europe/Berlin),执行原生 SQL 查询:
const [currentT] = await sequelize.query("SELECT CURRENT_TIME");
const [nowT] = await sequelize.query("SELECT NOW()");
console.log(currentT[0].current_time); // '15:00:45.709239+02'
console.log(nowT[0].now); // 2023-12-06T13:00:45.711Z ← 注意:这是 ISO UTC 字符串!你会发现:
-
CURRENT_TIME返回带+02的字符串(PostgreSQL 正确按会话时区渲染); -
NOW()却被 Sequelize 自动解析为 UTC 的Date对象(T13:00:45.711Z),看似比CURRENT_TIME晚 2 小时——实则因 Sequelize 在解析timestamptz类型时,未按数据库真实时区进行转换。
根本原因在于:Sequelize 默认将所有 timestamptz 值解析为 UTC 时间(new Date(...)),且不主动同步数据库会话时区。即使 PostgreSQL 服务端、操作系统、postgresql.conf 中 timezone = 'Europe/Berlin' 已正确设置,Sequelize 连接层仍可能忽略该配置。
✅ 正确解决方案是在初始化 Sequelize 实例时,显式声明 timezone 选项,确保其与数据库时区一致:
const sequelize = new Sequelize(
process.env.DB_DATABASE,
process.env.DB_USERNAME,
process.env.DB_PASSWORD,
{
host: process.env.DB_SERVER,
port: process.env.DB_PORT,
dialect: 'postgres',
timezone: '+01:00', // ✅ 强制 Sequelize 使用 GMT+1 解析时间戳
pool: {
min: 0,
max: 5,
idle: 10_000,
acquire: 30_000
}
}
);⚠️ 注意事项:
timezone值必须为 ISO 8601 格式的偏移量字符串(如'+01:00'),不可使用时区名称(如'Europe/Berlin'),否则 Sequelize 会静默忽略;- 该配置仅影响 JavaScript 端
Date对象的解析行为,不影响 SQL 执行时的数据库会话时区(若需统一会话时区,可额外执行SET TIME ZONE '+01:00';);- 若应用需支持多时区,建议始终在数据库中存储 UTC 时间,并在业务层做时区转换,避免依赖
timezone配置。
配置生效后,NOW() 将被正确解析为本地时区对应的 Date 实例(内部仍是 UTC,但 .toString() 和格式化输出将反映 +01:00 偏移),与 CURRENT_TIME 字符串的语义保持一致,彻底消除时间计算偏差。

















