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

PostgreSQL插入无时区时间值报错,如何正确存储仅时间部分?

解决PostgreSQL time字段插入失败问题

问题原因

JavaScript的Date对象本质是包含日期的时间戳,当你用new Date('12:22:00')创建实例时,它会自动拼接当前日期生成完整的时间戳。而从你的代码判断使用的MikroORM在将这类Date对象映射到PostgreSQL的time字段时,驱动无法正确提取纯时间部分,导致抛出"Invalid time value"错误。pgAdmin能直接成功是因为它接受纯字符串格式的时间值。

解决方案

方案1:直接传入字符串格式的时间值

既然PostgreSQL的time类型原生支持HH:MM:SS格式的字符串,直接将时间以字符串形式传入即可,无需通过Date对象转换:

// 实体定义保持不变
@Property({ type: 'time' })
startTime!: Date;

// 服务函数中直接传时间字符串
await this.persistAndFlush(context, shiftType, {
  name: input.name,
  startTime: '12:22:00',
  endTime: '12:22:00',
  status: activeStatus,
});

MikroORM会自动将字符串映射到PostgreSQL的time字段,读取时也会转换为Date对象(日期部分为当前日期,仅时间部分有效)。

方案2:自定义类型处理时间转换

如果希望代码中始终使用Date对象操作,可以自定义一个MikroORM类型,自动处理Date与PostgreSQLtime字段的转换:

import { Type, ConversionError } from '@mikro-orm/core';

export class TimeType extends Type {
  // 将JS值转换为数据库可接受的格式
  convertToDatabaseValue(value: Date | string): string {
    if (value instanceof Date) {
      // 提取HH:MM:SS格式的时间字符串
      return value.toTimeString().split(' ')[0];
    }
    if (typeof value === 'string') {
      return value;
    }
    throw new ConversionError(`Invalid time value: ${value}`);
  }

  // 将数据库值转换为JS的Date对象
  convertToJSValue(value: string): Date {
    const date = new Date();
    const [hours, minutes, seconds] = value.split(':').map(Number);
    date.setHours(hours, minutes, seconds, 0);
    return date;
  }

  // 指定数据库字段类型
  getColumnType() {
    return 'time';
  }
}

然后在实体中使用这个自定义类型:

@Property({ type: TimeType })
startTime!: Date;

这样无论你传入Date对象还是时间字符串,都能正确映射到PostgreSQL的time字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 04:57:47