如何解决 Sequelize 中日期格式化和时区问题

在 Sequelize 中,日期格式化和时区问题是常见的难点之一。本文将介绍如何解决这些问题,以便更好地使用 Sequelize 进行前端开发。

问题描述

在 Sequelize 中,日期格式化和时区问题主要表现为以下两种情况:

  1. Sequelize 读取数据库时,日期格式不正确。
  2. Sequelize 写入数据库时,日期会自动转换为 UTC 时间,导致时区不正确。

这些问题都会导致应用程序中的日期显示不正确,从而影响用户体验。

解决方案

问题一:Sequelize 读取数据库时,日期格式不正确

Sequelize 默认的日期格式为 ISO 8601 格式,即 "YYYY-MM-DDTHH:mm:ss.sssZ"。但是,数据库中存储的日期格式可能不同,比如 MySQL 中的 DATETIME 格式为 "YYYY-MM-DD HH:mm:ss"。为了解决这个问题,我们需要在 Sequelize 中指定日期格式。

下面是一个使用 Sequelize 读取 MySQL 数据库的示例:

const Sequelize = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
  dialect: 'mysql',
  dialectOptions: {
    timezone: 'Etc/GMT-8' // 设置时区
  },
  timezone: '+08:00', // 服务器时区
});

const User = sequelize.define('user', {
  id: {
    type: Sequelize.INTEGER,
    primaryKey: true,
    autoIncrement: true,
  },
  name: Sequelize.STRING,
  createdAt: Sequelize.DATE,
  updatedAt: Sequelize.DATE,
}, {
  timestamps: true,
  createdAt: 'created_at',
  updatedAt: 'updated_at',
  underscored: true,
  freezeTableName: true,
  tableName: 'users',
});

(async () => {
  const user = await User.findOne({
    where: { id: 1 },
    attributes: ['id', 'name', 'created_at', 'updated_at'],
  });

  console.log(user.toJSON());
})();

在上面的代码中,我们通过 dialectOptions.timezone 来指定数据库的时区,通过 timezone 来指定服务器的时区。在查询时,我们通过 attributes 参数来指定需要查询的字段,这样可以避免查询出不需要的字段。

问题二:Sequelize 写入数据库时,日期会自动转换为 UTC 时间

当我们使用 Sequelize 向数据库中写入日期时,Sequelize 会将日期自动转换为 UTC 时间,这会导致时区不正确。为了解决这个问题,我们可以使用 Moment.js 库来格式化日期。

下面是一个使用 Sequelize 向 MySQL 数据库写入日期的示例:

const Sequelize = require('sequelize');
const moment = require('moment-timezone');
const sequelize = new Sequelize('database', 'username', 'password', {
  dialect: 'mysql',
  dialectOptions: {
    timezone: 'Etc/GMT-8' // 设置时区
  },
  timezone: '+08:00', // 服务器时区
});

const User = sequelize.define('user', {
  id: {
    type: Sequelize.INTEGER,
    primaryKey: true,
    autoIncrement: true,
  },
  name: Sequelize.STRING,
  createdAt: Sequelize.DATE,
  updatedAt: Sequelize.DATE,
}, {
  timestamps: true,
  createdAt: 'created_at',
  updatedAt: 'updated_at',
  underscored: true,
  freezeTableName: true,
  tableName: 'users',
});

(async () => {
  const user = await User.create({
    name: 'John Doe',
    created_at: moment().tz('Asia/Shanghai').format('YYYY-MM-DD HH:mm:ss'),
    updated_at: moment().tz('Asia/Shanghai').format('YYYY-MM-DD HH:mm:ss'),
  });

  console.log(user.toJSON());
})();

在上面的代码中,我们通过 Moment.js 库来获取当前时间,并使用 tz 方法来指定时区。然后,我们使用 format 方法来将日期格式化为字符串,并将其写入数据库中。

总结

在 Sequelize 中,日期格式化和时区问题是常见的难点之一。本文介绍了如何解决这些问题,以便更好地使用 Sequelize 进行前端开发。在读取数据库时,我们需要在 Sequelize 中指定日期格式和时区;在写入数据库时,我们可以使用 Moment.js 库来格式化日期。希望本文对大家有所帮助。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65c18a98add4f0e0ffb840d5