Python 使用openpyxl读取为时间日期的浮动数值

Python 使用openpyxl读取为时间日期的浮动数值,python,python-3.x,openpyxl,Python,Python 3.x,Openpyxl,我有一个Excel电子表格,其中有一个字段包含小的%f.2值,如1.2、1.07、2.3等,出于某种原因,openpyxl将这些单元格作为1900日期读取。我见过很多次有人提出这个问题,但通常这些用户都在期待一个日期,并且得到了一个虚假的日期。我期待一个值,通常是x免责声明:我不知道如何使用openpyxl。但是,您主要只需要担心datetime模块 如果您知道哪些行应该是数字,您可以尝试使用以下代码将Excel日期格式转换为浮点数,如果是数字,则忽略它: import datetime imp

我有一个Excel电子表格,其中有一个字段包含小的%f.2值,如1.2、1.07、2.3等,出于某种原因,openpyxl将这些单元格作为1900日期读取。我见过很多次有人提出这个问题,但通常这些用户都在期待一个日期,并且得到了一个虚假的日期。我期待一个值,通常是x免责声明:我不知道如何使用openpyxl。但是,您主要只需要担心
datetime
模块

如果您知道哪些行应该是数字,您可以尝试使用以下代码将Excel日期格式转换为浮点数,如果是数字,则忽略它:

import datetime
import openpyxl
from openpyxl import load_workbook

# Source workbook - wb

wb = load_workbook(filename = r'C:\data\TEST.xlsx' , use_iterators=True)
ws = wb.get_sheet_by_name(name='QuoteFile ')

If val's a number, return it. Otherwise, take the difference between the datetime
and 1899-12-31 00:00:00. The way the datetimes work is they're internally a float,
being the number of days since the start of 1900. We get the number of seconds in
the delta (done through subtraction) and divide that by 86400 (the number of seconds
in a day).
def forcefloat(val):
    """If val's a number, return it. Otherwise, take the difference between the
    datetime and 1899-12-31 00:00:00. The way the datetimes work is they're
    internally a float, being the number of days since the start of 1900.
    We get the number of seconds in the delta (done through subtraction)
    and divide that by 86400 (the number of seconds in a day)."""
    if isinstance(val, (int, float)):
        return val
    assert isinstance(val, datetime.datetime)
    return (val - datetime.datetime(1899,12,31,0,0,0)).total_seconds() / 86400

for row in ws.iter_rows():
        print(
            row[0].internal_value,
            forcefloat(row[3].internal_value),
            row[4].internal_value,
            row[5].internal_value,
        )

print('Done')

虽然不是最优雅的解决方案,但它确实有效。

我认为我们正在取得进展。感谢关于类型(val)的提示,这帮助我理解了行迭代返回的内容。问题是它返回类型“datetime.datetime”。strtime(val…)似乎不喜欢传递给它的datetime.datetime,但需要一个字符串。我经历了几次转换(datetime.datetime-->字符串-->stream-->stream-->stream-->strptime,这似乎工作正常。现在我只需要两个字符串将其包装到lambda中。感谢datetime的提示。哦,这更简单。我将编辑问题以匹配。strtime部分实际上是将字符串转换为datetime.datetime。如果我们已经有了datetime.datetime,我们可以Don’不要跳过弦乐部分。它很有魅力!再次感谢。感谢你的提醒。这里的礼仪是新的。完成了,完成了。干杯。
20015   2.13    1.2 08/01/11
20015   5.03    1.2 08/01/11
20015   5.03    1.2 08/01/11
20015   5.51    1.2 08/01/11
20015   8.13    1.2 08/01/11
20015   5.60    1.2 08/01/11
20015   5.03    1.2 08/01/11
20015   1.50    1.2 08/01/11
20015   1.50    1.2 08/01/11
20015   1.50    1.2 08/01/11
20015   1.50    1.2 08/01/11
20015   1.50    1.2 08/01/11
20015   1.50    1.2 08/01/11
20015.0 1900-01-02 03:07:12 1.2 2011-08-01 00:00:00
20015.0 1900-01-05 00:43:12 1.2 2011-08-01 00:00:00
20015.0 1900-01-05 00:43:12 1.2 2011-08-01 00:00:00
20015.0 1900-01-05 12:14:24 1.2 2011-08-01 00:00:00
20015.0 1900-01-08 03:07:12 1.2 2011-08-01 00:00:00
20015.0 1900-01-05 14:24:00 1.2 2011-08-01 00:00:00
20015.0 1900-01-05 00:43:12 1.2 2011-08-01 00:00:00
20015.0 1.5 1.2 2011-08-01 00:00:00
20015.0 1.5 1.2 2011-08-01 00:00:00
20015.0 1.5 1.2 2011-08-01 00:00:00
20015.0 1.5 1.2 2011-08-01 00:00:00
20015.0 1.5 1.2 2011-08-01 00:00:00
20015.0 1.5 1.2 2011-08-01 00:00:00
import datetime
import openpyxl
from openpyxl import load_workbook

# Source workbook - wb

wb = load_workbook(filename = r'C:\data\TEST.xlsx' , use_iterators=True)
ws = wb.get_sheet_by_name(name='QuoteFile ')

If val's a number, return it. Otherwise, take the difference between the datetime
and 1899-12-31 00:00:00. The way the datetimes work is they're internally a float,
being the number of days since the start of 1900. We get the number of seconds in
the delta (done through subtraction) and divide that by 86400 (the number of seconds
in a day).
def forcefloat(val):
    """If val's a number, return it. Otherwise, take the difference between the
    datetime and 1899-12-31 00:00:00. The way the datetimes work is they're
    internally a float, being the number of days since the start of 1900.
    We get the number of seconds in the delta (done through subtraction)
    and divide that by 86400 (the number of seconds in a day)."""
    if isinstance(val, (int, float)):
        return val
    assert isinstance(val, datetime.datetime)
    return (val - datetime.datetime(1899,12,31,0,0,0)).total_seconds() / 86400

for row in ws.iter_rows():
        print(
            row[0].internal_value,
            forcefloat(row[3].internal_value),
            row[4].internal_value,
            row[5].internal_value,
        )

print('Done')