我们总是可以使用 knex 和 postgres 将日期列作为字符串 (varchar) 获取吗?

Can we always fetch date column as string (varchar) with knex and postgres?

我在 postgres 数据库中有一个类型为 date 的列。它是一个像生日一样的列,它只是一个日期,不需要有时间部分。

使用 knex 获取此列时,结果是一个 javascript 日期对象。大概是在做new Date(row.birthday),这是发送给客户端的结果

现在的问题是客户端收到的值是标准的 ISO 8601 格式,带有时间部分和 Z。当客户端尝试从该字符串创建新的 Date 对象时,根据客户端所在的位置,客户端可能有一个错误的日期值。

例如:

Date: 2018-06-15
Date sent to client: 2018-06-15T00:00:00Z

Client in +5:00     | Client in -5:00
2018-06-16 05:00:00 | 2018-05-15 10:00:00

如果服务器使用的是 UTC,这很好,我们可以只添加客户端的时区偏移量并获取原始日期,但这感觉有点脆弱,并且在本地开发(不是 UTC)期间会中断。

一个简单的解决方案是将日期部分作为字符串发送给客户端。但这需要在服务器中将日期存储为 varchar,我们不想这样做。我们将失去日期格式约束,并使使用 SQL.

进行基于日期的计算变得更加困难

我们可以在选择列时将该列转换为 varchar,但每次提取此 table 时,我们都需要冷静地执行此操作。这也意味着我们需要绕过 ORM(书架)来处理这个 table.

有没有一种简单的方法可以在 knex 或 bookshelf 或 postgres 本身中指定列需要存储为 date,并附带所有约束,但始终以 [=14 的形式获取=]?

node-postgres 驱动程序是根据日期列 (https://node-postgres.com/features/types#date-timestamp-timestamptz)

发送的数据实际创建 Date() 对象的部分

使用 postgres,您可以修改 node-pg 的类型解析器,如此处所述https://github.com/brianc/node-pg-types

日期类型类型的 oid 为 1082 可以通过以下查询获取

select typname, oid, typarray from pg_type where typname = 'date' order by oid;

因此,为了覆盖要作为字符串传递的日期类型,在设置数据库连接之前执行此操作就足够了(我想可以这样做,例如 knexfile.js):

var types = require('pg').types;
// override parsing date column to Date()
types.setTypeParser(1082, val => val); 

pg 设置 typeParser 可能是更好的答案,但您也可以使用 Bookshelf 的 Processor Plugin 来更改特定 date 属性的外观:

bookshelf.plugin('processor')
var MyModel = bookshelf.Model.extend({
  tableName: 'stuff',
  processors: {
    date: function(value) {
      /* you can use any other method for getting the date part */
      return value.toLocaleDateString()
    }
  }
})

为了获取字符串格式的本地时区时间,我们可以使用。

  var date =function(value) {
      /* you can use any other method for getting the date part */
        return value.toLocaleDateString()
  }

日期('1990-12-30T18:30:00.000Z'); 日期(值)

对我来说,投票最多的解决方案不起作用。它对我有用的是这个,使用 momentjs。

    import * as moment from 'moment';
    types.setTypeParser(1114, str => moment.utc(str).format());
    return knex({
        client: 'pg',
        connection: {
          host : 'localhost',
          user : 'postgres',
          password : '',
          database : 'localDB',
        }
    })

感谢Oleksii Rudenko https://60devs.com/working-with-postgresql-timestamp-without-timezone-in-node.html