比较postgres时间戳和JavaScript日期对象



我使用Node.js与pg查询Postgres数据库。我正在尝试执行以下查询:

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

some_date是我从Node.js传递的日期。

大多数时候我对此没有问题,因为日期/时间字符串的格式相同。然而,当引入时区时,问题就出现了。由于我在英国,我们在一年中的某些部分使用英国夏令时(GMT+1)。

当我将date_time_added从它的存储类型(带时区的时间戳)转换为日期时,时间默认为午夜。这样做的问题是,在BST期间,时间戳被转换为提前一天,时间设置为23:00而不是00:00,如下所示:

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

如果JavaScript有相同的行为,这不会是一个问题,但是如果我尝试以下操作:

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());

输出如下:

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

时间设置为午夜,而不是前一天的23:00。这对我来说是一个问题,因为这意味着日期不匹配,因此在数据库查询中不会返回行。

有没有人知道我如何能得到相同的行为日期(JS和Postgres)?这将是很好的,能够初始化一个新的日期对象与时间默认在相同的方式,当我转换到日期Postgres,但我不确定这是否可能。

发布,以防将来有人遇到这个问题。

这个问题是由于在Postgres中将时间戳转换为日期会丢失时区,因此它从午夜减去一个小时(因为将时区转换为日期时将时间设置为午夜),导致它在日期前一天变为23:00(因为BST是+1小时)。

我决定使用epoch时间,因为这使比较更容易满足我的需要。

我用下面的查询解决了这个问题:

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

这将保留时区并返回所选时间戳日期的历元时间(午夜)。'some_date_epoch'是JavaScript日期对象的纪元时间,使用Date. gettime()方法获得。这是我要在数据库中搜索的日期的历元时间。

例如,这是我如何在JavaScript中获得当前日期的历元时间,然后在数据库查询中使用:

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将被用来查询数据库。

最新更新