将 postgres 时间戳与 JavaScript 日期对象进行比较

时间:2021-01-20 14:15:37

标签: javascript postgresql date

我使用 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 相同的方式初始化一个新的日期对象,默认时间与我投射到日期时一样,但是我不确定这是否可行。

1 个答案:

答案 0 :(得分:0)

发布以防其他人将来遇到此问题。

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

我决定使用纪元时间,因为这使得比较更容易满足我的需求。

我使用以下查询解决了这个问题:

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 然后将用于查询数据库。