You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止TypeORM对PostgreSQL中已为UTC的日期进行额外转换?

解决TypeORM原生查询PostgreSQL DATE列被额外时区转换的问题

问题原因

这个转换是TypeORM依赖的pg(node-postgres)驱动默认行为导致的:驱动会把PostgreSQL的DATE类型自动解析为JavaScript的Date对象,而JavaScript Date本质是带时区的UTC时间戳,因此会将存储的日期(比如'1999-01-02')转换为对应UTC时区的零点前的时间(比如'1999-01-01T22:00:00.000Z',取决于本地时区偏移)。

解决方案

1. 全局修改pg驱动的DATE类型解析规则

在TypeORM数据源初始化前,覆盖pg驱动对DATE类型的解析逻辑,直接返回原始字符串:

import { DataSource } from "typeorm";
import { types } from "pg";

// 将DATE类型的解析器改为直接返回字符串
types.setTypeParser(types.builtins.DATE, (value) => value);

// 初始化TypeORM数据源
const dataSource = new DataSource({
  type: "postgres",
  host: "your-host",
  port: 5432,
  username: "your-username",
  password: "your-password",
  database: "your-db",
  entities: [/* 你的实体类 */],
  // 其他配置...
});

2. 在原生查询中显式转换DATE列为字符串

如果不想全局修改驱动配置,可以在SQL语句中使用PostgreSQL的TO_CHAR函数,直接将DATE列转为标准日期字符串:

const response = await queryRunner.query(`
  SELECT 
    name,
    age,
    TO_CHAR(dob, 'YYYY-MM-DD') AS dob,
    address
  FROM MY_VIEW WHERE AGE=23
`);

3. 手动处理查询结果

拿到查询结果后,将Date对象转换为日期字符串:

const response = await queryRunner.query('SELECT * FROM MY_VIEW WHERE AGE=23');

// 遍历结果,处理DATE列
const processedData = response.map(item => ({
  ...item,
  dob: item.dob instanceof Date 
    ? item.dob.toISOString().split('T')[0] 
    : item.dob
}));

内容的提问来源于stack exchange,提问作者mleko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 11:05:29