OleDB读取Excel时datetime类型值返回错误数值怎么办
问题原因
秒位出现随机乱值是ACE OLEDB引擎读取Excel日期类型时的典型浮点解析错误,核心诱因是连接字符串里错误添加了FMT=Delimited配置——这个参数只在读取CSV这类分隔文本时生效,套用到Excel格式读取时,会强制引擎用文本解析逻辑处理Excel存储日期用的双精度浮点数,直接造成小数位精度截断,偏差刚好落在秒位区间。
另外现有连接字符串缺少xlsx格式的必填解析标识,也会进一步加剧类型识别异常。
修复方案
不用反复测试调整IMEX、HDR参数:这两个参数分别控制列的读写权限、是否将首行识别为表头,和日期解析的精度逻辑完全无关,改了也解决不了问题。直接按优先级选以下方案即可:
- 方案1:修正连接字符串配置
删除错误的FMT=Delimited参数,补全格式标识和全列类型扫描配置,修正后的扩展属性代码如下:
关键配置说明:sqlBuilder.Add("Extended Properties", "Excel 12.0 Xml;HDR=No;IMEX=1;CharacterSet=65001;TypeGuessRows=0;ImportMixedTypes=Text");Excel 12.0 Xml是读取xlsx格式的必填标识,缺省状态下引擎会按老版本xls格式解析,很容易触发类型识别错误TypeGuessRows=0会强制引擎扫描整列所有数据判定类型,避免因前几行数据类型和后续不一致导致的类型误判
- 方案2:绕开引擎自带日期转换,手动解析原始值
如果调整连接字符串后仍存在偶发精度偏差,直接读取单元格存储的原始双精度值,用.NET内置方法转日期即可,从根源上规避引擎的转换bug:
Excel本身存储日期的本质就是双精度浮点数:整数部分代表从1900年1月1日起的偏移天数,小数部分代表当日时刻占全天的比例,// 从DataReader读取到对应列的值后做转换 if (reader.GetValue(列序号) is double oaDateValue) { DateTime correctTime = DateTime.FromOADate(oaDateValue); // 转换后的值和Excel内存储的日期完全一致,不会出现秒位错乱 }DateTime.FromOADate就是专门适配这种存储格式的官方转换方法,精度完全可控。
内容的提问来源于stack exchange,提问作者Arpit Gupta
相关产品推荐
相关产品推荐

