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

如何在Prisma、Node.js、GraphQL及Prisma Migrate中实现日期时间转相对格式?

在 Prisma + Node.js + GraphQL 栈中实现人性化相对时间格式

一、应用层实现相对时间转换

相对时间格式化属于应用层逻辑,不需要在数据库层面处理,推荐借助成熟的时间库快速实现,避免自己编写复杂的时间差计算逻辑。

1. 使用 date-fns 实现(推荐)

date-fns 轻量且支持多语言本地化,适合 Node.js 环境:

  • 安装依赖:
npm install date-fns
  • 在 GraphQL Resolver 中封装转换函数:
const { formatDistanceToNow } = require('date-fns');
const { zhCN } = require('date-fns/locale');

// 转换函数:接收Date对象,返回中文相对时间
function getRelativeTime(date) {
  return formatDistanceToNow(date, {
    addSuffix: true, // 自动添加"前"后缀
    locale: zhCN, // 启用中文本地化
  });
}

// 在Resolver中调用
const resolvers = {
  Query: {
    post: async (_, { id }, { prisma }) => {
      const post = await prisma.post.findUnique({ where: { id } });
      return {
        ...post,
        // 新增相对时间字段返回给前端
        relativeCreatedAt: getRelativeTime(post.createdAt),
      };
    },
  },
};

2. 使用 luxon 实现

luxon 功能更丰富,支持时区处理:

  • 安装依赖:
npm install luxon
  • 转换函数示例:
const { DateTime } = require('luxon');

function getRelativeTime(date) {
  return DateTime.fromJSDate(date)
    .setLocale('zh-CN')
    .toRelative(); // 直接返回"X分钟前"格式的字符串
}

3. 自定义 GraphQL 标量(复用场景)

如果多个类型需要返回相对时间,可以定义自定义标量自动处理转换:

const { GraphQLScalarType } = require('graphql');
const { Kind } = require('graphql/language');
const { formatDistanceToNow } = require('date-fns');
const { zhCN } = require('date-fns/locale');

const RelativeTimeScalar = new GraphQLScalarType({
  name: 'RelativeTime',
  description: '人性化相对时间格式,如"一分钟前"',
  serialize(value) {
    if (!(value instanceof Date)) {
      throw new Error('RelativeTime 仅接受 Date 类型值');
    }
    return formatDistanceToNow(value, { addSuffix: true, locale: zhCN });
  },
  parseValue(value) {
    return new Date(value); // 解析客户端传入的时间(可选,若仅只读可忽略)
  },
  parseLiteral(ast) {
    if (ast.kind === Kind.STRING) {
      return new Date(ast.value);
    }
    return null;
  },
});

然后在 GraphQL Schema 中声明使用:

type Post {
  id: ID!
  createdAt: DateTime!
  relativeCreatedAt: RelativeTime!
}

二、Prisma Migrate 的相关说明

相对时间格式化不需要在 Prisma Migrate 中配置,Prisma Migrate 仅负责管理数据库表结构。你只需要在 schema.prisma 中正确定义日期时间字段即可:

model Post {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now()) // 默认填充当前时间
  updatedAt DateTime @updatedAt // 自动更新为修改时间
  // 其他业务字段...
}

执行迁移命令创建/更新数据库表:

npx prisma migrate dev --name init-post-table

数据库存储的是标准 UTC 时间,后续在应用层通过上述方法转换为相对时间即可。

关键注意事项

  • 不要在数据库中存储相对时间:相对时间是动态变化的(如"一分钟前"会随时间变为"两分钟前"),数据库应存储固定的原始时间,应用层实时计算相对值。
  • 前端处理可选:如果前端需要实时更新相对时间,可以将原始日期时间传给前端,用前端时间库(如 dayjs、date-fns)处理,减少后端计算压力。

内容的提问来源于stack exchange,提问作者amghare

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 06:35:31