Python 如何将给定序号(从Excel)转换为日期
我有一个值38142,我需要使用python将其转换为日期格式。Python 如何将给定序号(从Excel)转换为日期,python,excel,python-2.7,date,Python,Excel,Python 2.7,Date,我有一个值38142,我需要使用python将其转换为日期格式。 如果在excel中使用此数字,然后右键单击并格式化单元格,此时该值将转换为04/06/2004,我需要使用python获得相同的结果。如何实现这一点Excel中的偏移量是自1900/01/01以来的天数,1是1900年1月1日,因此将天数作为时间增量添加到1899/12/31: from datetime import datetime, timedelta def from_excel_ordinal(ordinal, _ep
如果在excel中使用此数字,然后右键单击并格式化单元格,此时该值将转换为04/06/2004,我需要使用python获得相同的结果。如何实现这一点Excel中的偏移量是自1900/01/01以来的天数,
1
是1900年1月1日,因此将天数作为时间增量添加到1899/12/31:
from datetime import datetime, timedelta
def from_excel_ordinal(ordinal, _epoch0=datetime(1899, 12, 31)):
if ordinal >= 60:
ordinal -= 1 # Excel leap year bug, 1900 is not a leap year!
return (_epoch0 + timedelta(days=ordinal)).replace(microsecond=0)
对于1900/02/28之后的任何日期,您必须将序号调整一天;Excel从Lotus1-2-3继承了一个新概念,并将1900视为闰年。上面的代码返回59
和60
的datetime(1900,2,28,0,0)
,以更正此错误,小数点在[59.0-61.0]范围内,都是当天00:00:00.0和23:59:59.99999之间的时间
上面的代码还支持用分数表示时间的序列,但由于Excel不支持微秒,因此会删除这些序列
from datetime import datetime, timedelta
def from_excel_ordinal(ordinal, epoch=datetime(1900, 1, 1)):
# Adapted from above, thanks to @Martijn Pieters
if ordinal > 59:
ordinal -= 1 # Excel leap year bug, 1900 is not a leap year!
inDays = int(ordinal)
frac = ordinal - inDays
inSecs = int(round(frac * 86400.0))
return epoch + timedelta(days=inDays - 1, seconds=inSecs) # epoch is day 1
excelDT = 42548.75001 # Float representation of 27/06/2016 6:00:01 PM in Excel format
pyDT = from_excel_ordinal(excelDT)
上述答案仅适用于日期值,但我在这里扩展了上述解决方案,以包括时间并返回日期时间值。我将推荐以下内容:
import pandas as pd
def convert_excel_time(excel_time):
return pd.to_datetime('1900-01-01') + pd.to_timedelta(excel_time,'D')
或
摘自
我在尝试执行上述操作时遇到了这个问题,但针对df中的整个列。我创建了这个函数,它为我做到了:
import pandas as pd
from datetime import datetime, timedelta
import copy as cp
def xlDateConv(df, *cols):
tempDt = []
fin = cp.deepcopy(df)
for col in [*cols]:
for i in range(len(fin[col])):
tempDate = datetime(1900, 1, 1)
delta = timedelta(float(fin[col][i]))
tempDt.append(pd.to_datetime(tempDate+delta))
fin[col] = tempDt
tempDt = []
return fin
请注意,您需要将每个列(作为字符串)作为一个参数键入,这很可能会得到改进(例如,列列表作为输入)。此外,它还返回原始df的副本(不更改原始df)
顺便说一句,部分灵感来自此()。如果您正在与熊猫合作,这可能会很有用
import xlrd
import datetime as dt
def from_excel_datetime(x):
return dt.datetime(*xlrd.xldate_as_tuple(x, datemode=0))
df['date'] = df.excel_date.map(from_excel_datetime)
如果日期延迟了4年,您可以尝试使用datemode 1
:param datemode:0:1900为基础,1:1904为基础。这是一个奇怪的顺序;你确定04/06/2004是正确的吗?如果值38142代表天,那么它将是1993/12/25或1993/10/27的偏移量,这取决于你对月份的理解。建议它应该是自1900/01/01以来的天数,这就是
date.fromordinal()
有。但该数字缺少一个数字。我的文件有一个值,我不知道它的序号与否。我的客户说它的序号,并告诉我“如果你想找到实际日期,只需在excel中对给定值进行格式化,我就得到了这个值”@martijnpieters是的,这确实是一个序数,但Excel中有一个错误,使我对我最初的理论大打折扣。相关的,老问题:太好了,非常感谢@MartijnPieters@Krish:这个错误是由Joel Spolsky推广的:你确定纪元不是1899年12月31日吗?datetime(1899,12,31)+timedelta(序数-(序数>59)
@J.F.Sebastian我在这里坚持使用Excel文档;在这里减去一个相对于1900-01-01的值没有什么区别。@FinanceGuyThatCantCode:the\u epoch
参数用于将值缓存为局部变量,仅此而已。这有助于避免为每次调用创建它,或查找全局变量(稍微慢一点)。非常感谢这个xldate-to-datetime(44000)给出了2020-06-20,答案是2020-06-18
import xlrd
import datetime as dt
def from_excel_datetime(x):
return dt.datetime(*xlrd.xldate_as_tuple(x, datemode=0))
df['date'] = df.excel_date.map(from_excel_datetime)