简体   繁体   中英

Compare postgres Timestamp with JavaScript Date Object

I am using Node.js with pg to query a Postgres database. I am trying to execute the following query:

SELECT COUNT(*) FROM table_name WHERE date_time_added::date = some_date;

some_date is the date I pass from Node.js.

I have no problems with this most of the time, as both date/time strings are in the same format. However, issues arise when Timezones are introduced. As I am located in the UK, we use British Summer Time (GMT+1) for some parts of the year.

When I cast date_time_added from it's stored type (timestamp with timezone) to date, the time defaults to midnight. The issue with this is that during BST, the timestamp is cast to one day earlier, and the time set to 23:00 instead of 00:00, as shown below:

{ date_time_added: 2020-09-28T23:00:00.000Z }

This wouldn't be a problem if JavaScript had the same behaviour, however if I try the following:

const date1 = new Date(2020, 8, 29, 10, 47, 54);
console.log(date1.toString());
date1.setHours(0);
date1.setMinutes(0);
date1.setSeconds(0);
date1.setMilliseconds(0);
console.log(date1.toString());

The following output is produced:

"Tue Sep 29 2020 10:47:54 GMT+0100 (British Summer Time)"
"Tue Sep 29 2020 00:00:00 GMT+0100 (British Summer Time)"

The time is set to midnight rather than 23:00 the day before. This is a problem for me as this means the dates don't match, and therefore the row is not returned in the database query.

Does anyone know how I can get the same behaviour for both dates (JS and Postgres)? It would be good to be able to initialise a new Date Object with the time defaulting in the same way as Postgres does when I cast to date, however I am not sure if this is possible.

Posting in case anyone else comes across this problem in the future.

This issue was caused because casting a timestamp to a date in Postgres loses the timezone, therefore it was subtracting an hour from midnight (as the time is set to midnight when casting a timezone to a date), causing it to become 23:00 one day before the date (as BST is +1 hour).

I decided to use epoch time as this made comparison easier for my needs.

I solved this by using the following query:

SELECT COUNT(*) FROM table_name WHERE extract(epoch from date_trunc('day', date_time_added)) = some_date_epoch;

This keeps the timezone and returns the epoch time (at midnight) for the date of the selected timestamp. 'some_date_epoch' is the epoch time of a JavaScript Date Object, obtained using the Date.getTime() method. This is the epoch time of the date I'd like to search for in the database.

For example, this is how I'd get the epoch time for the current date in JavaScript, to then use in the database query:

let currentDate = new Date();
currentDate.setHours(0);
currentDate.setMinutes(0);
currentDate.setSeconds(0);
currentDate.setMilliseconds(0);
let currentDateEpoch = (currentDate.getTime() / 1000); //Convert to seconds to match Postgres

currentDateEpoch would then be used to query the database.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM