Skip to content

Fix: 修复 Excel 日期单元格被识别为 BIGINT#3282

Merged
t8y2 merged 2 commits into
t8y2:mainfrom
zipg:codex/issue3276-excel-date-import
Jul 13, 2026
Merged

Fix: 修复 Excel 日期单元格被识别为 BIGINT#3282
t8y2 merged 2 commits into
t8y2:mainfrom
zipg:codex/issue3276-excel-date-import

Conversation

@zipg

@zipg zipg commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

问题原因

Excel 内部使用数字序列存储日期和时间。Calamine 启用日期转换后可以把带日期/时间格式的单元格转换为 ExcelDateTime,但导入解析阶段原本直接调用 to_string(),得到的仍是 459960.5 这类原始序列值,后续类型推断因此会误判为 BIGINT 或小数。

另外,单靠转换后的时间是否为 00:00:00 无法区分 date-only、午夜 datetime、time-only 和 duration,容易丢失 Excel 原始格式语义。

修改内容

  • 启用 Calamine 的日期转换能力。
  • 解析 XLSX 的 styles.xml 和 worksheet cell style,保留原始单元格格式分类。
  • 支持识别 date-only、time-only、datetime、duration。
  • date-only 输出 YYYY-MM-DD,可继续推断为 DATE
  • datetime 输出 YYYY-MM-DD HH:MM:SS[.fraction],午夜 datetime 不再被误降成 date。
  • time-only 输出 HH:MM:SS[.fraction],不再拼出 1899-12-311904-01-01 伪日期。
  • duration 输出持续时间格式,例如 36:00:00
  • 无法获取格式分类时采用保守策略,避免伪造日期语义。
  • 补充真实 .xlsx 测试,覆盖 date-only、午夜 datetime、time-only、duration、1900/1904 日期系统。

验证

  • cargo fmt --package dbx-core
  • cargo test -p dbx-core --no-default-features table_import::tests --lib
  • cargo check -p dbx-core --no-default-features
  • git diff --check
  • GitHub CI 已通过

Closes #3276

@t8y2 t8y2 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-311904-01-01,变成并不存在的时间戳。

建议在解析 workbook 时保留原始单元格格式分类,再据此决定输出形式;如果当前 Calamine API 无法提供足够信息,则需要采用不会伪造日期语义的保守处理。请同时补充真实 .xlsx 测试,至少覆盖 date-only、午夜 datetime、time-only、duration,以及 1900/1904 日期系统。

@zipg
zipg force-pushed the codex/issue3276-excel-date-import branch from 9e3be9f to 64cbf8d Compare July 13, 2026 08:58
@zipg

zipg commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

已按审核意见更新:

  • 解析 XLSX 的 styles.xml 与 worksheet cell style,保留 date-only、time-only、datetime、duration 的原始格式语义。
  • 午夜 datetime 不再因为时间是 00:00:00 被降成 DATE。
  • time-only 不再拼出 1899/1904 的伪日期;duration 按时长格式输出。
  • 补充真实 .xlsx 测试,覆盖 1900/1904 日期系统、date-only、午夜 datetime、time-only、duration。

已验证:

  • cargo fmt --package dbx-core
  • cargo test -p dbx-core --no-default-features table_import::tests --lib
  • cargo check -p dbx-core --no-default-features
  • git diff --check

@t8y2 t8y2 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@t8y2
t8y2 merged commit 2cb58b0 into t8y2:main Jul 13, 2026
7 checks passed
@t8y2

t8y2 commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Thanks for the contribution! Merged in 2cb58b0, will be released in the next version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] 导入excel时,单元格格式为日期的会被识别成BIGINT

2 participants