29

我需要将日期转换为我正在编写的数据处理脚本的 Excel 序列号。通过在我的 OpenOffice Calc 工作簿中处理日期,我能够推断出 '1-Jan 1899 00:00:00' 映射到数字零。

我编写了以下函数将 python 日期时间对象转换为 Excel 序列号:

def excel_date(date1):
    temp=dt.datetime.strptime('18990101', '%Y%m%d')
    delta=date1-temp
    total_seconds = delta.days * 86400 + delta.seconds
    return total_seconds

但是,当我尝试一些示例日期时,这些数字与我在 Excel(以及 OpenOffice Calc)中将日期格式化为数字时得到的数字不同。例如,测试“2009-03-20”在 Python 中给出 3478032000,而 excel 将序列号呈现为 39892。

上面的公式有什么问题?

*注意:我使用的是 Python 2.6.3,因此无法访问 datetime.total_seconds()

4

6 回答 6

49

Excel“序列日期”格式似乎实际上是自 1900-01-00 以来的数,其中的小数部分是一天的一小部分,基于http://www.cpearson.com/excel/datetime。 .htm _ (我想这个日期实际上应该被认为是 1899-12-31,因为没有一个月的第 0 天这样的事情)

所以,它似乎应该是:

def excel_date(date1):
    temp = dt.datetime(1899, 12, 30)    # Note, not 31st Dec but 30th!
    delta = date1 - temp
    return float(delta.days) + (float(delta.seconds) / 86400)
于 2012-03-05T22:22:07.803 回答
15

虽然这与 excel 序列日期格式并不完全相关,但这是将 python 日期时间导出到 Excel 的首选。我发现特别有用和简单的就是使用 strftime 导出。

import datetime
current_datetime = datetime.datetime.now()
current_datetime.strftime('%x %X')

这将以以下格式输出“06/25/14 09:59:29”,Excel 接受该格式作为有效日期/时间,并允许在 Excel 中进行排序。

于 2014-06-25T14:03:41.477 回答
9

如果问题是我们想要 DATEVALUE() excel 日期序列号,可以使用 toordinal() 函数。Python 序列号从第 1 年的 Jan1 开始,而 excel 从 1900 年 1 月 1 日开始,因此应用偏移量。另请参阅 excel 1900 闰年错误(https://support.microsoft.com/en-us/help/214326/excel-incorrectly-assumes-that-the-year-1900-is-a-leap-year

def convert_date_to_excel_ordinal(day, month, year) :

    offset = 693594
    current = date(year,month,day)
    n = current.toordinal()
    return (n - offset)
于 2017-11-24T18:47:19.183 回答
1

使用 3rd 方xlrd.xldate模块,您可以提供一个结构化的元组,(year, month, day, hour, minute, second)并在必要时从任何微秒组件计算一天分数:

from datetime import datetime
from xlrd import xldate
from operator import attrgetter

def excel_date(input_date):
    components = ('year', 'month', 'day', 'hour', 'minute', 'second')
    frac = input_date.microsecond / (86400 * 10**6)  # divide by microseconds in one day
    return xldate.xldate_from_datetime_tuple(attrgetter(*components)(input_date), 0) + frac

res = excel_date(datetime(1900, 3, 1, 12, 0, 0, 5*10**5))
# 61.50000578703704
于 2019-01-28T19:42:08.873 回答
0

根据@akgood 的回答,当日期时间在 1/0/1900 之前,返回值是错误的,修正后的返回表达式可能是:

def excel_date(date1):
    temp = dt.datetime(1899, 12, 30)    # Note, not 31st Dec but 30th!
    delta = date1 - temp
    return float(delta.days) + (-1.0 if delta.days < 0 else 1.0)*(delta.seconds)) / 86400
于 2020-01-15T12:04:21.943 回答
0

当我使用csv 包创建电子表格进行测试时,这很有效:

from datetime import datetime

def excel_date(date1):
    return date1.strftime('%x %-I:%M:%S %p')

now = datetime.now()
current_datetime=now.strftime('%x %-I:%M:%S %p')
time_data.append(excel_date(datetime.now()))
...
于 2020-11-23T21:18:56.177 回答