You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sequelize关联查询Posts与Likes表时如何格式化createdAt日期字段

Sequelize 自定义格式化 createdAt 等 datetime 字段方案

你当前使用 NodeJS + Express + Sequelize + MySQL 技术栈,Posts 表通过 hasMany 关联 Likes 表,查询帖子列表时需要对返回结果中的时间字段做自定义格式化,以下是三种可直接落地的实现方式,可根据项目需求选择:


方案1:全局统一配置(所有模型生效,复用性最高)

如果项目中所有表的时间字段都需要统一格式,直接在 Sequelize 初始化实例时添加配置即可,一次配置全局生效,关联查询出的Likes表时间字段也会自动格式化。

// 初始化sequelize的配置文件
const { Sequelize } = require('sequelize');
const dayjs = require('dayjs'); // 轻量时间处理库,需提前执行 npm i dayjs 安装

const sequelize = new Sequelize('你的数据库名', '数据库账号', '数据库密码', {
  host: 'localhost',
  dialect: 'mysql',
  timezone: '+08:00', // 国内场景配置东八区,避免时间和本地差8小时
  define: {
    timestamps: true,
    // 全局时间字段getter,统一格式化输出
    getterMethods: {
      createdAt() {
        const rawTime = this.getDataValue('createdAt');
        // 可自定义修改格式,比如要YYYY/MM/DD就改format参数
        return rawTime ? dayjs(rawTime).format('YYYY-MM-DD HH:mm:ss') : null;
      },
      updatedAt() {
        const rawTime = this.getDataValue('updatedAt');
        return rawTime ? dayjs(rawTime).format('YYYY-MM-DD HH:mm:ss') : null;
      }
    }
  }
});

方案2:单模型独立配置(仅指定表生效)

如果不需要全局修改,只需要给Posts、Likes等特定表的时间字段做格式化,直接在对应模型定义中添加字段 getter 即可,以你现有Posts模型为例,修改后代码如下:

const dayjs = require('dayjs');
module.exports = (sequelize, DataTypes) => {
  const Posts = sequelize.define("Posts", {
    title: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    postText: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    username: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    // 单独给createdAt配置格式化规则
    createdAt: {
      type: DataTypes.DATE,
      get() {
        const rawValue = this.getDataValue('createdAt');
        return rawValue ? dayjs(rawValue).format('YYYY-MM-DD HH:mm:ss') : null;
      }
    },
    updatedAt: {
      type: DataTypes.DATE,
      get() {
        const rawValue = this.getDataValue('updatedAt');
        return rawValue ? dayjs(rawValue).format('YYYY-MM-DD HH:mm:ss') : null;
      }
    }
  });

  Posts.associate = (models) => {
    Posts.hasMany(models.Comments, {
      onDelete: "cascade",
    });

    Posts.hasMany(models.Likes, {
      onDelete: "cascade",
    });
  };

  return Posts;
};

Likes模型的时间格式化按相同逻辑添加配置即可,关联查询时会自动应用格式化规则。


方案3:查询结果遍历处理(单次接口定制,灵活度最高)

如果不想修改全局或模型配置,仅当前帖子列表接口需要特殊时间格式,直接在查询拿到结果后遍历处理字段即可,修改你现有接口代码如下:

const dayjs = require('dayjs');
router.get("/", validateToken, async (req, res) => {
  const listOfPosts = await Posts.findAll({
    include: [Likes],
    order: [["createdAt", "desc"]],
  });

  // 格式化帖子及关联点赞数据的时间字段
  const formattedPosts = listOfPosts.map(post => {
    const postData = post.toJSON(); // Sequelize实例转普通对象才可修改属性
    postData.createdAt = dayjs(postData.createdAt).format('YYYY-MM-DD HH:mm:ss');
    postData.updatedAt = dayjs(postData.updatedAt).format('YYYY-MM-DD HH:mm:ss');
    // 处理关联的Likes记录时间
    postData.Likes = postData.Likes.map(like => {
      like.createdAt = dayjs(like.createdAt).format('YYYY-MM-DD HH:mm:ss');
      like.updatedAt = dayjs(like.updatedAt).format('YYYY-MM-DD HH:mm:ss');
      return like;
    })
    return postData;
  })

  const likedPosts = await Likes.findAll({ where: { UserId: req.user.id } });
  // 格式化当前用户点赞记录的时间
  const formattedLikedPosts = likedPosts.map(like => {
    const likeData = like.toJSON();
    likeData.createdAt = dayjs(likeData.createdAt).format('YYYY-MM-DD HH:mm:ss');
    likeData.updatedAt = dayjs(likeData.updatedAt).format('YYYY-MM-DD HH:mm:ss');
    return likeData;
  })

  res.json({ listOfPosts: formattedPosts, likedPosts: formattedLikedPosts });
});

补充说明

  • 若不想引入dayjs依赖,可使用原生Date对象的toLocaleString方法实现基础格式化:new Date(rawTime).toLocaleString('zh-CN', {timeZone: 'Asia/Shanghai'}),但自定义格式的灵活度较低。
  • 必须配置对应时区,否则Sequelize默认使用UTC时间,国内场景下返回的时间会比实际时间早8小时。

内容的提问来源于stack exchange,提问作者M7md-Dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 14:09:20