xlrd是否可以从Excel中正确检索日期变量?

时间:2012-12-04 16:51:34

标签: python datetime xlrd

当我偶然发现以下问题时,我试图将多表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

3 个答案:

答案 0 :(得分:1)

我很确定xlrd能够判断单元格在Excel格式化为日期,并自行转换为Python date对象。但这并非万无一失。

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

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

哪一天应该避免(a)有一天你在191年1月1日开始添加和(b)有一天你要添加(我猜)它是datetime对象而不是date,可能会将其推到第二天。不过,这只是猜测。

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

print datetime.datetime(1900,1,1,0,0,0) + datetime.timedelta(days=Data - 2)

答案 1 :(得分:1)

不。这里有两件事。

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

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

答案 2 :(得分:1)

早期答案只是部分正确。

额外信息:

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

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

1904系统:最早的非模糊日期时间是1904-01-02T00:00:00,表示为1.0。

Book.datemode的xlrd中提供了哪个日期系统有效。

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一起分发的文档中。