【问题标题】:Python - not getting correct datetime upon reading time from excel filePython - 从excel文件中读取时间时没有得到正确的日期时间
【发布时间】:2016-04-15 18:24:55
【问题描述】:

我有一个 excel 文件,它有 3 列作为日期时间或日期或时间字段。我正在通过xlrd 包阅读它,我想我得到了 milliseconds 的时间,当我试图将它转换回日期时间时,我得到了错误的结果。

我也尝试将文件转换为csv。这也无济于事,而且我得到了我无法理解的奇怪的日期时间格式。

这是我尝试使用xlrd 格式的方法。我更喜欢使用带有.xlrs 扩展名的文件作为输入,因为否则我每次得到一个新的输入文件时都必须将excel 文件转换为.csv

from xlrd import open_workbook
import os,pickle,datetime

def main(path, filename, absolute_path_organisation_structure):
    absolute_filepath = os.path.join(path,filename)

    wb = open_workbook(absolute_filepath)
    for sheet in wb.sheets():
        number_of_rows = sheet.nrows
        number_of_columns = sheet.ncols

        for row_index in xrange(1, sheet.nrows):
            row=[]
            for col_index in xrange(4,7): #4th and 6th columns are date fields
                row.append(sheet.cell(row_index, col_index).value)

            print(row)  #Relevant list formed with 4th, 5th and 6th columns
            print(datetime.datetime.fromtimestamp(float(row[0])).strftime('%Y-%m-%d %H:%M:%S'))


path = "C:\\Users\\***************\\NEW DATA"
MISfile  = "P2P_2015 - Copy.xlsx"
absolute_path_organisation_structure = "C:\\Users\\******************NEW DATA\\organisation.csv"
main(path, MISfile, absolute_path_organisation_structure)

结果:

[42011.46789351852, u'Registered', 42009.0]
1970-01-01 17:10:11
[42011.46789351852, u'Sent for CTG1 approval', 42010.0]
1970-01-01 17:10:11
[42011.46789351852, u'Sent back', 42010.0]
1970-01-01 17:10:11
[42011.46789351852, u'Registered', 42011.0]
1970-01-01 17:10:11
[42011.46789351852, u'Sent for CTG1 approval', 42011.0]
1970-01-01 17:10:11
[42011.46789351852, u'Sent for CTG2 approval', 42012.0]
1970-01-01 17:10:11
[42011.46789351852, u'CTG2 Approved', 42012.0]
1970-01-01 17:10:11
[42011.46789351852, u'Sent back', 42013.0]
1970-01-01 17:10:11
[42170.61667824074, u'Registered', 42144.0]
1970-01-01 17:12:50
[42170.61667824074, u'Registered', 42144.0]
1970-01-01 17:12:50
[42170.61667824074, u'Sent back', 42165.0]
1970-01-01 17:12:50
[42170.61667824074, u'Sent back', 42165.0]
1970-01-01 17:12:50
[42170.61667824074, u'Registered', 42170.0]
1970-01-01 17:12:50
[42170.61667824074, u'Registered', 42170.0]
1970-01-01 17:12:50

实际输入文件:(从excel复制)

1/7/2015 11:13  Registered  1/5/2015 0:00
1/7/2015 11:13  Sent for CTG1 approval  1/6/2015 0:00
1/7/2015 11:13  Sent back   1/6/2015 0:00
1/7/2015 11:13  Registered  1/7/2015 0:00
1/7/2015 11:13  Sent for CTG1 approval  1/7/2015 0:00
1/7/2015 11:13  Sent for CTG2 approval  1/8/2015 0:00
1/7/2015 11:13  CTG2 Approved   1/8/2015 0:00
1/7/2015 11:13  Sent back   1/9/2015 0:00
6/15/2015 14:48 Registered  5/20/2015 0:00
6/15/2015 14:48 Registered  5/20/2015 0:00
6/15/2015 14:48 Sent back   6/10/2015 0:00
6/15/2015 14:48 Sent back   6/10/2015 0:00
6/15/2015 14:48 Registered  6/15/2015 0:00
6/15/2015 14:48 Registered  6/15/2015 0:00

为什么我无法正确读取日期?为什么它们不简单地作为字符串出现以便我可以轻松地转换它们?

【问题讨论】:

    标签: python excel csv datetime xlrd


    【解决方案1】:

    如果要读取的 Excel 文件是表格可以简单直接地使用pandas.read_excel。 使用pandas.to_datetime 转换日期后

    from __future__ import absolute_import, division, print_function
    import os
    import pandas as pd
    
    def main(path, filename, absolute_path_organisation_structure):
        absolute_filepath = os.path.join(path,filename)
        #Relevant list formed with 4th, 5th and 6th columns
        df = pd.read_excel(absolute_filepath, header=None, parse_cols=[4,5,6])
        # Transform column 0 and 2 to datetime
        df[0] = pd.to_datetime(df[0])
        df[2] = pd.to_datetime(df[2])
        print(df)
    
    path = "C:\\Users\\***************\\NEW DATA"
    MISfile  = "P2P_2015 - Copy.xlsx"
    main(path, MISfile,None)
    

    【讨论】:

    • 我不知道pandas 的excel 阅读能力。即使在我已经选择了一个有效的答案之后,也感谢您提供帮助。从日期列中删除标题后,此解决方案也有效。
    【解决方案2】:

    xldate_as_tuple(xldate, datemode) [#]

    将 Excel 数字(假定表示日期、日期时间或时间)转换为适合提供给 datetime 或 mx.DateTime 构造函数的元组。

    来源:http://www.lexicon.net/sjmachin/xlrd.html#xlrd.xldate_as_tuple-function

    用法示例:How to use ``xlrd.xldate_as_tuple()``

    【讨论】:

    • @Shivendra dt = xldate_as_tuple(cell.value, wb.datemode) 然后pydate = datetime.datetime(*dt)
    【解决方案3】:

    问题是您将 Excel 日期时间值解释为 UNIX 时间戳,而它们不是同一事物。要查找的警告标志是结果值都接近 UNIX 纪元 (1970-01-01)。

    您可以使用in this answer 描述的方法将 Excel 日期时间转换为 UNIX。

    Windows/Mac Excel 2011

    Unix Timestamp = (Excel Timestamp - 25569) * 86400
    

    Mac Excel 2007

    Unix Timestamp = (Excel Timestamp - 24107) * 86400
    

    如果你应用这个转换,你应该得到正确的输出:

    timestamp = (float(row[0]) - 25569) * 86400
    datetime.datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')
    

    【讨论】:

    • 由于时间不够,我将仅使用该解决方案。但我仍然得到不正确的时间值。是否也可以像在 excel 文件中一样获得它?
    • @Shivendra 尝试来自@khajvah 的答案,它使用xlrd API 来获取正确的值。
    • @Shivendra 如果只是时间值不正确,您可能需要调整时区
    猜你喜欢
    • 2014-10-30
    • 2020-01-09
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-30
    • 1970-01-01
    相关资源
    最近更新 更多