如何阻止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
相关产品推荐
相关产品推荐

