Fix: 修复 Excel 日期单元格被识别为 BIGINT#3282
Conversation
t8y2
left a comment
There was a problem hiding this comment.
request changes: 当前转换会丢失部分 Excel 时间格式的语义。
xlsx_datetime_label 仅根据转换后的时间是否为 00:00:00 决定输出 DATE 还是 TIMESTAMP,但 Calamine 的 ExcelDateTime 无法区分 date-only、time-only 和 datetime 格式。因此:
yyyy-mm-dd hh:mm:ss格式的午夜时间会被降成DATE;hh:mm:ss格式的纯时间会被加上1899-12-31或1904-01-01,变成并不存在的时间戳。
建议在解析 workbook 时保留原始单元格格式分类,再据此决定输出形式;如果当前 Calamine API 无法提供足够信息,则需要采用不会伪造日期语义的保守处理。请同时补充真实 .xlsx 测试,至少覆盖 date-only、午夜 datetime、time-only、duration,以及 1900/1904 日期系统。
9e3be9f to
64cbf8d
Compare
|
已按审核意见更新:
已验证:
|
t8y2
left a comment
There was a problem hiding this comment.
Maintainer patch applied in 52e9a89.
The XLSX style map used absolute worksheet coordinates while Calamine row iteration used coordinates relative to the used range. Worksheets whose data started outside A1 could therefore lose date/time style classification and infer the wrong import type.
The patch applies the worksheet range origin to both row and column lookups and adds a real sparse XLSX regression starting at C3.
Validation:
- XLSX offset regression test passed
- table import tests: 28 passed
- cargo check -p dbx-core --no-default-features
- git diff --check
|
Thanks for the contribution! Merged in 2cb58b0, will be released in the next version. |
问题原因
Excel 内部使用数字序列存储日期和时间。Calamine 启用日期转换后可以把带日期/时间格式的单元格转换为
ExcelDateTime,但导入解析阶段原本直接调用to_string(),得到的仍是45996、0.5这类原始序列值,后续类型推断因此会误判为BIGINT或小数。另外,单靠转换后的时间是否为
00:00:00无法区分 date-only、午夜 datetime、time-only 和 duration,容易丢失 Excel 原始格式语义。修改内容
styles.xml和 worksheet cell style,保留原始单元格格式分类。YYYY-MM-DD,可继续推断为DATE。YYYY-MM-DD HH:MM:SS[.fraction],午夜 datetime 不再被误降成 date。HH:MM:SS[.fraction],不再拼出1899-12-31或1904-01-01伪日期。36:00:00。.xlsx测试,覆盖 date-only、午夜 datetime、time-only、duration、1900/1904 日期系统。验证
cargo fmt --package dbx-corecargo test -p dbx-core --no-default-features table_import::tests --libcargo check -p dbx-core --no-default-featuresgit diff --checkCloses #3276