插件窝 干货文章 使用Prisma查询MySQL数据库,时间差了8小时,怎么办?

使用Prisma查询MySQL数据库,时间差了8小时,怎么办?

时区 Prisma MySQL item 396    来源:    2025-04-01

Prisma 查询 MySQL 时间差8小时问题解决方案

问题原因

当Prisma查询MySQL数据库时出现8小时时间差,通常是由于以下原因之一:

  1. MySQL服务器时区设置与应用程序时区不一致
  2. Prisma连接配置未正确处理时区
  3. 数据库连接字符串中未指定时区

解决方案

方案1:在Prisma连接字符串中指定时区

修改你的prisma/schema.prisma文件中的datasource配置:

datasource db {
  provider = "mysql"
  url      = "mysql://user:password@localhost:3306/dbname?connection_limit=5&timezone=Asia/Shanghai"
}

Asia/Shanghai替换为你所在的时区(如Asia/TokyoEurope/Paris等)。

方案2:在MySQL服务器层面设置时区

  1. 登录MySQL服务器
  2. 执行以下命令查看当前时区设置: sql SHOW VARIABLES LIKE '%time_zone%';
  3. 如果需要修改,可以执行: sql SET GLOBAL time_zone = '+8:00';sql SET GLOBAL time_zone = 'Asia/Shanghai';

方案3:在应用程序中转换时区

如果你无法修改数据库配置,可以在应用层处理:

// 查询后转换时区
const results = await prisma.yourModel.findMany();
const adjustedResults = results.map(item => ({
  ...item,
  dateField: new Date(item.dateField.getTime() + 8 * 60 * 60 * 1000)
}));

方案4:使用Prisma中间件自动转换

const prisma = new PrismaClient();

prisma.$use(async (params, next) => {
  const result = await next(params);
  if (params.model && params.action === 'findMany') {
    return result.map(item => {
      if (item.dateField) {
        return {
          ...item,
          dateField: new Date(item.dateField.getTime() + 8 * 60 * 60 * 1000)
        };
      }
      return item;
    });
  }
  return result;
});

最佳实践

  1. 统一时区:确保数据库、应用服务器和客户端使用相同的时区设置
  2. UTC存储:考虑将所有时间以UTC格式存储在数据库中,只在显示时转换为本地时间
  3. 文档记录:在项目文档中明确记录时区处理策略

验证方案

修改后,可以通过以下方式验证:

const test = await prisma.$queryRaw`SELECT NOW() as currentTime`;
console.log(test);

检查输出时间是否与当前本地时间一致。