Node-PostgreSQL插入expiration_date时gmt+0300时区不识别如何解决
问题根因
你遇到的报错本质是日期格式不匹配导致:
- 你插入users表时是把
created_date存为YYYY-MM-DD格式的字符串,符合Postgres date类型的存储要求 - 但你从数据库查询
created_date字段时,数据库驱动会默认将date类型字段转为JS Date对象,你调用toString()后会得到带时区信息的完整日期字符串(类似Fri Jul 12 2024 00:00:00 GMT+0300),你的replace逻辑只修改了开头的年份,剩下的时区信息Postgres无法识别,因此抛出时区不支持的错误。
可行解决方案
方案1:JS侧正确处理日期格式
修改genCard中日期处理的逻辑,不要用toString()加字符串替换的方式计算过期日期,直接操作Date对象后转成标准的YYYY-MM-DD格式:
const genCard=(req,res,db)=>{ const {id,cardType} =req.body; db.select('created_date').from('users').where("id","=",id) .then(data=>{ // 直接操作Date对象计算4年后的日期 const createdDate = new Date(data[0].created_date); createdDate.setFullYear(createdDate.getFullYear() + 4); const expirationDate = createdDate.toISOString().slice(0,10); db('card_info') .insert({ card_number:Math.floor(Math.random()*1E17), owner_id:id, expiration_date: expirationDate, cvv:Math.floor(Math.random()*1E3), card_type:cardType }) .returning('*') .then(card=>{ res.json(card[0]); }) .catch(err=>res.json(err.message)) }) .catch(err=>res.json(err)); }
方案2:直接用Postgres内置函数计算(更推荐)
不用先查询users表,直接在插入时通过数据库内置的日期运算得到过期日期,减少一次数据库交互,也完全避免日期格式问题:
const genCard=(req,res,db)=>{ const {id,cardType} =req.body; db('card_info') .insert({ card_number:Math.floor(Math.random()*1E17), owner_id:id, // 直接用Postgres的日期运算加4年 expiration_date: db.raw('(SELECT created_date + INTERVAL \'4 years\' FROM users WHERE id = ?)', [id]), cvv:Math.floor(Math.random()*1E3), card_type:cardType }) .returning('*') .then(card=>{ res.json(card[0]); }) .catch(err=>res.json(err.message)) }
额外优化建议
- 你当前生成的银行卡号是17位随机数,注意常规银行卡/信用卡号为16位,且需要保证唯一性,建议增加重复校验逻辑
- CVV生成后如果不足3位,建议补前导零,避免存为非3位的数字
内容的提问来源于stack exchange,提问作者NevinTroy
相关产品推荐
相关产品推荐

