My computer timezone offset is UTC/GMT +3 hours
.
My table in database is defined as such.
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)
);
I execute such query:
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()])
})
}
Under the hood this invokes I write to database using pg.ClientBase.query(sql, params)
, which is created using const client = await pg.Pool.connect()
Then I read it back, but instead of getting the string "2024-07-09T12:32:30.214Z"
I get "2024-07-09T09:32:30.227Z"
. Here is some code that tests that and prints to console.
// 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())
resulting log:
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
2024-07-09T12:32:30.214Z
2024-07-09T09:32:30.227Z
It seems that this pg
library for some inexplicable reason by default interprets postgres timestamps without timezone as local timestamps.
How to configure pg
library client
object to retrieve all postgres timestamps without timestamp as either naive timestamps or, better yet, utc timestamps.
2
Answers
Indeed I used similar solution to @Adesoji Alu but a little more refined. I was waiting to see if it would be also possible to fix the issue of writing naive datetime via
pg
as UTC via Pool config optionparseInputDatesAsUTC: true
, but that thing does not work.Then instead of
new Pool(config)
usenew UtcPoolFactory(config).create()
In a nutshell TIMESTAMP WITHOUT TIME ZONE doesn’t save any timezone related information. if you give date time with timezone info,it takes date & time only and ignores timezone
see this documentation here: https://www.postgresql.org/docs/current/datatype-datetime.html