Sequelize设置时区以查询

9

我目前在项目中使用Sequelizepostgres。我需要更改查询,以便返回带有时区偏移的created_at列。

var sequelize = new Sequelize(connStr, {
dialectOptions: {
    useUTC: false //for reading from database
},
timezone: '+08:00' //for writing to database

});

但这会影响整个数据库。但我只需要在选择查询中使用时区。有人知道该怎么做吗?


你可能需要使用带有 timestamp AT TIME ZONE 的原始查询来解决这个问题。 - Vao Tsun
我也尝试过,它可以工作,但不正确。当我在查询构建器中运行查询时,它可以正常工作。但是当我使用Sequelize时,它会进行错误的计算。 - Danis
有关此事有任何更新吗?我也遇到了类似的问题。 - Soham Lawar
3个回答

4

无论我在phpmyadmin中设置时区为何,我仍然得到服务器的created_at和updated_at时间。 即使点击该字段也显示错误的时区。 我可能做错了什么? - Luke Galea
也许这只是一个表象问题。 - Developerium
这个能在postgres上运行吗?我已经尝试了,但没有成功。我已经尝试了几种方法,但时区设置似乎无法与sequelize和postgres一起使用。 - Martin Naughton

2

我建议将moment.js与以下方法结合使用:

如果您需要参数化时区,则可能需要为每个单独的查询添加偏移量或向表中添加一个额外的字段来指示时区,因为似乎sequelize不允许参数化的getter。

例如:

const moment = require('moment.js');
const YourModel = sequelize.define('your_model', {
  created_at: {
    type: Sequelize.DATE,
    allowNull: false,
    get() {
      return moment(this.getDataValue('created_at'))
        .utcOffset(this.getDataValue('offset'));
    },
  },
});

另一种可能性是以类似的方式扩展模型原型的实例方法,这允许您在需要created_at值时指定偏移量:
const moment = require('moment.js');
YourModel.prototype.getCreatedAtWithOffset = function (offset) {
  return moment(this.created_at).utcOffset(offset);
};

1

为了正确使用带有时区的查询,请准备好您的pg驱动程序,详见此处

const pg = require('pg')

const { types } = pg

// we must store dates in UTC
pg.defaults.parseInputDatesAsUTC = true

// fix node-pg default transformation for date types
// https://github.com/brianc/node-pg-types
// https://github.com/brianc/node-pg-types/blob/master/lib/builtins.js
types.setTypeParser(types.builtins.DATE, str => str)
types.setTypeParser(types.builtins.TIMESTAMP, str => str)
types.setTypeParser(types.builtins.TIMESTAMPTZ, str => str)

在初始化Sequelize实例之前,必须进行初始化。

现在,您可以运行一个查询,指定您想要获取日期的时区

假设我们进行一个SQL查询,选择所有用户字段和“createdAt”在时区'Europe/Kiev'中:

SELECT *, "createdAt"::timestamptz AT TIME ZONE 'Europe/Kiev' AS "createdAt" FROM users WHERE id = 1;

# or with variables
SELECT *, "createdAt"::timestamptz AT TIME ZONE :timezone AS "createdAt" FROM users WHERE id = :id;

对于Sequelize(针对用户模型),代码将如下所示:
```javascript ```
请注意,此处未提供具体的代码实现。
sequelize.findOne({
  where: { id: 1 },
  attributes: {
    include: [
      [sequelize.literal(`"User"."createdAt"::timestamptz AT TIME ZONE 'Europe/Kiev'`), 'createdAt'],
      
      // also you can use variables, of course remember about SQL injection:
      // [sequelize.literal(`"User"."updatedAt"::timestamptz AT TIME ZONE ${timeZoneVariable}`), 'updatedAt'],
    ]
  }
});

1
这段代码节省了我很多时间。谢谢// 我们必须将日期存储为UTC pg.defaults.parseInputDatesAsUTC = true - hsyn.ozkara

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接