如何在 Ruby 中将 MS Excel 日期从浮点数转换为日期格式?

2023-11-21

尝试在 ruby​​ 脚本中使用 roo gem 解析 XLSX 文件。

在 Excel 中,日期以 DDDDD.ttttt 格式存储为浮点数或整数,从1900-01-00 (00 no 01)。因此,为了转换诸如 40396 之类的日期 - 您需要1900-01-00 + 40396你应该得到 2010-10-15,但我得到 2010-08-08。

我使用 active_support/time 进行计算,如下所示:

Time.new("1900-01-01") + 40396.days

是我计算错误还是主动支持存在错误?

我在 Windows 7 + 最新的 active_support gem (3.2.1) 上运行 ruby​​ 1.9.3-mri

EDIT

我正在查看 Excel 中的旧文件,其中包含错误的数据 - 我的脚本/控制台提取了正确的数据 - 因此我很困惑 - 我做的一切都是正确的,除了使用正确的文件!该死的通宵达旦!

感谢大家的回复,我将把问题保留在这里,以防有人需要有关如何使用 ruby​​ 从 excel 转换日期的信息。

同样对于遇到此问题的其他人 - 电子表格 gem 目前不支持正确读取 XLSX 文件(v 0.7.1) - 所以我使用 roo 进行读取,使用 axlsx 进行写入。


您的日期编号存在差一错误 - 由于 Lotus 1-2-3 中的一个错误,Excel 和其他电子表格程序 30 多年来一直小心翼翼地保持与该程序的兼容性。

最初,第 1 天是 1900 年 1 月 1 日(正如您所说,这将使第 0 天等于 1899 年 12 月 31 日)。但是 Lotus 错误地将 1900 年视为闰年,因此,如果您使用现在的 Lotus 数字并向后计数,正确地使 1900 年成为平年,那么 1900 年 3 月 1 日之前的所有日期数字都太高了。第 1 天变为 1899 年 12 月 31 日,第 0 天则移回 30 日。因此,基于 Lotus 的电子表格中日期算术的纪元实际上是 1899 年 12 月 30 日星期六。(现代 Excel 和其他一些电子表格将 Lotus 错误兼容性扩展得足够远,足以显示 1900 年 2 月实际上有第 29 天,因此它们将标记日期0 “12 月 31 日”,同时同意这是星期六!但其他基于 Lotus 的电子表格不会这样做,Ruby 当然也不会。)

然而,即使考虑到此错误,您所说的示例也是不正确的:莲花日编号 40,396 是 2010 年 8 月 6 日,而不是 10 月 15 日。我已经在 Excel、LibreOffice 和 Google 表格中确认了这一对应关系,所有这些都一致。你一定在某个地方交叉过例子。

这是进行转换的一种方法:

Time.utc(1899,12,30) + 40396.days #=> 2010-08-06 00:00:00 UTC

或者,您可以利用另一个已知的对应关系。 Ruby(以及一般的 POSIX 系统)的零时间是 1970 年 1 月 1 日午夜 GMT。 1970年1月1日是莲花日25,569。只要您记得以 UTC 进行计算,您还可以执行以下操作:

Time.at( (40396 - 25569).days ).utc # => 2010-08-06 00:00:00 UTC

在任何一种情况下,您可能都想为纪元日期声明一个符号常量(或者是Time代表 1899-12-30 或 POSIX“第 0 天”值 25,569 的对象)。

您可以将这些调用替换为.days如果不需要,可以乘以 86400(每天秒数)active_support/core_ext/integer/time对于其他任何事情,并且不想仅仅为此加载它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Ruby 中将 MS Excel 日期从浮点数转换为日期格式? 的相关文章

随机推荐