0

当我偶然发现以下问题时,我试图将多张 Excel 工作簿读入 SPSS:当我使用 xlrd 将日期变量从 Excel 读入 Python 时,它似乎在日期上增加了 2 天。或者我从 Excel 格式到更人性化的表示形式的转换可能是不正确的。谁能告诉我下面的代码有什么问题?

import xlwt,datetime 
wb=xlwt.Workbook() 
ws=wb.add_sheet("date_1") 
fmt = xlwt.easyxf(num_format_str='M/D/YY') 
ws.write(0,0,datetime.datetime.now(),fmt) 
wb.save(r"d:\temp\datetest.xls") 

#Now open Excel file manually -> date is correct

import xlrd
wb=xlrd.open_workbook(r"d:\temp\datetest.xls") 
ws=wb.sheets()[0]
Data = ws.row_values(0)[0]
print datetime.datetime(1900,1,1,0,0,0)+datetime.timedelta(days=Data)

#Now date is 2 days off
4

3 回答 3

1

没有。这里发生了两件事。

1 - 在 Excel 中,“1”而不是“0”对应于 1900 年 1 月 1 日 2 - Excel 包括 1900 年 2 月 29 日(从未发生过),说明了第二天的差异。出于向后兼容性的原因,这是故意这样做的。

考虑到这两点似乎可以解决所有问题。

于 2012-12-05T12:15:13.923 回答
1

我很确定它xlrd能够判断单元格何时在 Excel 中格式化为日期,并自行转换为 Pythondate对象。不过,这并不是万无一失的。

您的问题可能是从开始datetime.datetime(1900,1,1,0,0,0)并添加timedelta到它 - 您可能想尝试:

datetime.date(1899,12,31) + datetime.timedelta(days=Data)

这应该避免(a)你从 1900 年 1 月 1 日开始添加的一天和(b)你添加的一天(我猜)让它成为一个datetime对象而不是date,这可能是推动它一直持续到第二天。不过,这只是一个猜测。

或者,如果您已经知道它始终是两天,那么您为什么不这样做呢?

print datetime.datetime(1900,1,1,0,0,0) + datetime.timedelta(days=Data - 2)
于 2012-12-04T20:26:50.947 回答
1

早期的答案只是部分正确。

额外信息:

有两种 Excel 日期系统:(1900 (Windows) 和 1904 (Mac))。

1900 系统:最早的非模糊日期时间是 1900-03-01T00:00:00,表示为 61.0。

1904系统:最早的无歧义日期时间为1904-01-02T00:00:00,表示为1.0。

哪个日期系统有效,可在 xlrd 中找到Book.datemode

xlrd 提供了一个函数xldate_as_tuple来处理上述所有问题。这段代码:

print datum
print datetime.datetime(1900, 1, 1) + datetime.timedelta(days=datum)
print datetime.datetime(1900, 3, 1) + datetime.timedelta(days=datum - 61)
tup = xlrd.xldate_as_tuple(datum, wb.datemode)
print tup
print datetime.datetime(*tup)

产生:

41274.4703588
2013-01-02 11:17:19
2012-12-31 11:17:19
(2012, 12, 31, 11, 17, 19)
2012-12-31 11:17:19

当 wb.datemode 为 0 (1900) 时。

这些信息都包含在随 xlrd 分发的文档中。

于 2012-12-31T00:30:23.157 回答