
Sequelize 默认使用 UTC 时区解析 PostgreSQL 返回的时间戳,而数据库服务器可能配置为本地时区(如 GMT+1),导致 CURRENT_TIME 和 now() 等函数在 Sequelize 中被错误转换,引发时间逻辑偏差。
sequelize 默认使用 utc 时区解析 postgresql 返回的时间戳,而数据库服务器可能配置为本地时区(如 gmt+1),导致 `current_time` 和 `now()` 等函数在 sequelize 中被错误转换,引发时间逻辑偏差。
在使用 Sequelize 连接 PostgreSQL 时,你可能会观察到一个看似矛盾的现象:直接在 pgAdmin 或 psql 中执行 SELECT CURRENT_TIME 或 SELECT NOW() 返回符合预期的本地时区时间(例如 '14:00:30.633552+01'),但通过 Sequelize 执行相同查询后,JavaScript Date 对象却显示为 UTC 时间(如 2023-12-06T13:00:45.711Z)——即使数据库和操作系统均配置为 GMT+1。
这是因为 Sequelize 在接收 PostgreSQL 的 timestamptz 类型响应后,默认以 +00:00(UTC)为基准进行解析,而非自动适配数据库会话的 timezone 设置。PostgreSQL 的 NOW() 返回的是带时区的时间戳(timestamptz),其值在存储/传输时已标准化为 UTC,但 Sequelize 的 JavaScript 客户端需明确知道“应以哪个时区显示或反序列化”,否则会默认转为本地(Node.js 进程)时区或 UTC,造成视觉与逻辑错位。
✅ 正确解法是在 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', // ← 关键:匹配数据库 timezone 设置(如 Europe/Berlin)
pool: {
min: 0,
max: 5,
idle: 10_000,
acquire: 30_000
}
}
);
⚠️ 注意事项:
-
timezone值支持 ISO 8601 偏移格式(如'+01:00')或 IANA 时区名(如'Europe/Berlin'),后者更推荐——它能自动处理夏令时(DST)切换; - 该选项仅影响 Sequelize 对时间字段的序列化/反序列化行为(即 JS
Date对象的构造),不影响 SQL 查询本身或数据库内部存储逻辑; - 若应用需跨多时区运行,建议统一在数据库层使用
timestamptz+ UTC 存储,并在业务层按用户时区格式化显示,而非依赖 Sequelize 的timezone选项做全局转换; - 验证是否生效:执行
SELECT NOW(), CURRENT_TIME;后检查返回的 JSDate对象.toISOString()与.toString()输出差异,或使用.toLocaleString('en-US', { timeZone: 'Europe/Berlin' })辅助比对。
简言之:Sequelize 不自动继承 PostgreSQL 的 timezone 参数,必须主动配置 timezone 选项,才能确保时间语义一致、避免调度、统计、日志等场景出现整点偏差。










