从PostgreSQL到Express后端获取Timestamp而非Date的问题
PostgreSQL Date类型在Express pg包中的时区与格式问题
问题1:为什么DATE类型返回Timestamp格式?怎么拿到纯Date结果?
PostgreSQL的date类型本身是不带时区的纯日期,但Node.js的pg驱动会默认把它转换成JavaScript的Date对象——而JS的Date本质是带UTC时间戳的对象,所以打印时会显示成带时分秒的Timestamp格式。
要获取纯日期格式,有几种可行方案:
- 方案1:SQL查询时转成字符串
直接在SELECT语句中将date字段转为文本格式,返回结果就是纯日期字符串:const listResult = await db.query("SELECT id, list_date::TEXT FROM task_lists WHERE user_id = $1", [req.user.id]); // 返回示例:{ id: 1, list_date: '2024-07-17' } - 方案2:自定义pg驱动的类型解析器
覆盖pg对date类型的默认解析逻辑,直接返回日期字符串:
配置后执行查询,const { types } = require('pg'); // PostgreSQL的date类型OID为1082,直接返回原始字符串 types.setTypeParser(1082, (val) => val);list_date会直接返回'2024-07-18'这类纯日期字符串。 - 方案3:在JS中处理Date对象
如果需要保留Date对象,可自行提取本地日期格式:const formattedRows = listResult.rows.map(row => ({ ...row, list_date: row.list_date.toLocaleDateString('en-CA') // 输出YYYY-MM-DD格式 }));
问题2:为什么返回日期比存储的早一天?怎么解决?
这是时区不匹配导致的:
PostgreSQL的date类型存储的是纯日期(如2024-07-17),但pg驱动默认会把它解析成UTC时区的当天0点。从返回的2024-07-16T18:30:00.000Z能推断出你的本地时区是UTC+5:30,UTC时间的16号18:30加上5.5小时就是本地时间的17号0点,所以打印UTC时间时会显示成前一天的傍晚。
解决方法:
- 方法1:转成本地时区的日期
用JS Date对象的方法提取对应时区的日期:// 指定时区提取日期 row.list_date.toLocaleDateString('en-CA', { timeZone: 'Asia/Kolkata' }); // 或手动拼接本地日期 const date = row.list_date; const localDate = `${date.getFullYear()}-${String(date.getMonth()+1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; - 方法2:在SQL中返回带时区的日期
将date字段转换为指定时区的时间,让驱动解析成正确的本地时间:const listResult = await db.query(` SELECT id, list_date AT TIME ZONE 'Asia/Kolkata' AS list_date FROM task_lists WHERE user_id = $1 `, [req.user.id]); - 方法3:配置pg驱动的时区
连接数据库时指定时区,让驱动直接按指定时区解析日期:const db = new Pool({ // 其他数据库配置 timezone: 'Asia/Kolkata' // 替换为你的实际时区 });
内容的提问来源于stack exchange,提问作者Aakarshit
相关产品推荐
相关产品推荐

