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

C# DateTime?通过Dapper/Npgsql存入PostgreSQL date列丢失一天问题

问题原因分析

核心问题出在C# DateTime的时区信息(Kind属性)与Npgsql的转换逻辑上:

  • PostgreSQL的date类型是无时区的纯日期值,不存储时间或时区信息。
  • 当直接传入DateTime?对象时,Npgsql会根据该DateTime的Kind属性做时区转换:
    • 如果Kind是Local(本地时间)或Unspecified(未指定时区),Npgsql默认会将其转换为UTC时间,再提取日期部分存入date列。
    • 假设你的本地时区是UTC+X(比如东八区),本地时间的2024-05-20 00:00:00转UTC后是2024-05-19 16:00:00,对应的UTC日期就是前一天,最终存入数据库的就是2024-05-19。
  • 当把DateTime?转为字符串传入时,PostgreSQL会直接用数据库所在时区解析字符串为日期,跳过了Npgsql的时区转换逻辑,因此得到正确日期。
解决方案

提供三种可行的解决方式,按需选择:

1. 将DateTime转换为UTC后传入

确保传入的DateTime是UTC时区,避免转换后的日期偏移:

var q = connection.QuerySingle<ReturnToOfficeOrder>(sql, new
{
    Rtoon = r.rtoon?.ToUniversalTime()
});

2. 修改Npgsql连接字符串,禁用时区转换

在连接字符串中添加DateTimeKind=Unspecified,让Npgsql将所有DateTime对象视为无时区的纯日期时间,直接映射到PostgreSQL的date列:

Host=your_host;Database=phoenix;Username=your_user;Password=your_pwd;DateTimeKind=Unspecified

3. 使用Npgsql专属的NpgsqlDate类型

直接使用Npgsql提供的NpgsqlDate类型(专门对应PostgreSQL的date类型),彻底规避时区转换问题:

var q = connection.QuerySingle<ReturnToOfficeOrder>(sql, new
{
    Rtoon = r.rtoon.HasValue ? new NpgsqlDate(r.rtoon.Value) : (NpgsqlDate?)null
});

内容的提问来源于stack exchange,提问作者Alan Wayne

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 16:53:11