我的电脑时区偏移量是
UTC/GMT +3 hours
。
我在数据库中的表就是这样定义的。
CREATE TABLE public.order_invoices (
created_at timestamp NOT NULL,
updated_at timestamp NOT NULL,
order_id uuid NOT NULL,
document_id varchar(100) NULL,
status varchar(20) NOT NULL,
CONSTRAINT order_invoices_pkey PRIMARY KEY (order_id)
);
我执行这样的查询:
markInvoiceWaitingForApf(order: Order): Promise<void> {
return this.sql.executeInTransaction(async tx => {
await tx.executeStatement(
`INSERT INTO order_invoices(order_id, status, created_at, updated_at)
VALUES ($1, $2, $3, CURRENT_TIMESTAMP)
ON CONFLICT (order_id) DO
UPDATE SET updated_at = CURRENT_TIMESTAMP, status = $2
WHERE order_invoices.status = 'WAITING_FOR_APF'`,
[order.id, OrderInvoiceStatus.WAITING_FOR_APF, parseISO(order.orderDate).toISOString()])
})
}
在幕后,这会调用我使用
pg.ClientBase.query(sql, params)
写入数据库,这是使用 const client = await pg.Pool.connect()
创建的
然后我读了一遍,但没有得到字符串
"2024-07-09T12:32:30.214Z"
,而是得到了"2024-07-09T09:32:30.227Z"
。这是一些测试并打印到控制台的代码。
// Arrange
const order = randomOrder({ orderDate: new Date().toISOString() })
console.log('HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH')
console.log(parseISO(order.orderDate).toISOString())
await t.context.sut.markInvoiceWaitingForApf(order)
const temp = await t.context.testSql.getOrderInvoice(order.id)
console.log(temp.updatedAt.toISOString())
结果日志:
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
2024-07-09T12:32:30.214Z
2024-07-09T09:32:30.227Z
似乎这个
pg
库出于某种莫名其妙的原因默认将没有时区的postgres时间戳解释为本地时间戳。
如何配置 pg
库 client
对象来检索所有没有时间戳的 postgres 时间戳,或者将其作为朴素时间戳,或者更好的是 utc 时间戳。
简而言之,没有时区的时间戳不保存任何时区相关信息。如果您提供带有时区信息的日期时间,则仅需要日期和时间并忽略时区
// PostgreSQL timestamp without timezone type ID
const TIMESTAMPTZ_OID = 1114;
// Override the default parser
pgTypes.setTypeParser(TIMESTAMPTZ_OID, (stringValue) => {
// Return the UTC timestamp
return new Date(`${stringValue}Z`);
});
请参阅此处的文档:https://www.postgresql.org/docs/current/datatype-datetime.html