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

Adonis.js API返回时间与PostgreSQL数据库timestamptz数据不匹配

解决Adonis.js API返回timestamptz时间与时区不匹配问题

问题本质

PostgreSQL的timestamptz类型实际存储的是UTC时间,你看到的数据库显示值2024-02-25 18:00:00.000 +0800是数据库客户端自动将UTC时间转换为本地(+8)时区后的结果;而Adonis.js默认会把数据库返回的时间序列化为UTC格式的ISO 8601字符串(即2024-02-25T10:00:00.000Z),二者是同一个时间点的不同时区展示形式。如果需要API返回与数据库显示一致的+8时区时间,可通过以下方式调整:

解决方案

1. 全局配置统一时区输出

修改Adonis.js的全局配置,让所有时间字段都以指定时区格式返回:
打开config/app.ts,添加或调整时区与日期格式配置:

export default defineConfig({
  // 其他配置项...
  timezone: 'Asia/Shanghai', // 指定为+8时区
  dateFormat: 'YYYY-MM-DD HH:mm:ss.SSS ZZ', // 匹配数据库显示的格式
})

注:Adonis版本不同配置项可能略有差异,v5可在locale模块下设置时区,v6可通过date配置块调整

2. 模型层单独处理特定时间字段

如果仅需特定模型的时间字段返回指定时区,可在模型中重写字段的序列化逻辑:

import { DateTime } from 'luxon'
import { BaseModel, column } from '@ioc:Adonis/Lucid/Orm'

export class YourModel extends BaseModel {
  @column.dateTime({
    autoCreate: true,
    serialize: (value: DateTime) => {
      return value.setZone('Asia/Shanghai').toFormat('yyyy-MM-dd HH:mm:ss.SSS ZZ')
    }
  })
  public createdAt: DateTime

  // 对updatedAt等其他时间字段重复上述逻辑
}

这里借助Adonis默认依赖的Luxon库,将UTC时间转换为Asia/Shanghai时区后格式化输出。

3. 自定义序列化器全局处理

通过自定义序列化器统一处理所有模型的时间字段:
首先创建自定义序列化器文件app/Serializers/CustomSerializer.ts:

import { LucidSerializer } from '@ioc:Adonis/Lucid/Serializer'
import { DateTime } from 'luxon'

export default class CustomSerializer extends LucidSerializer {
  protected serializeDate(value: DateTime) {
    return value.setZone('Asia/Shanghai').toFormat('yyyy-MM-dd HH:mm:ss.SSS ZZ')
  }
}

然后在模型中指定使用该序列化器:

import { BaseModel } from '@ioc:Adonis/Lucid/Orm'
import CustomSerializer from 'App/Serializers/CustomSerializer'

export class YourModel extends BaseModel {
  public static serializer = () => CustomSerializer
}

验证

修改配置或代码后重启服务,调用API即可得到与数据库显示一致的2024-02-25 18:00:00.000 +0800格式时间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 05:53:22