2015-04-01 117 views
6

我有一个值38142我需要使用python将其转换为日期格式。 如果在excel中使用这个数字,并在那时做一个右键点击和格式化单元格的值将被转换为04/06/2004,我需要使用python相同的结果。我怎样才能达到这个目标如何将给定的序号(从Excel)转换为日期

+0

这是一个奇怪的序数;你确定04/06/2004是正确的吗?如果价值38142代表* days *,那么这将是1993/12/25或1993/10/27的偏移量,具体取决于您解释的月份。 – 2015-04-01 09:29:18

+0

[将日期转换为数字的公式](http://stackoverflow.com/q/19721416)表明它应该是自1900/01/01以来的几天,这是'date.fromordinal()'的作用。但那个号码就是一个数字。 – 2015-04-01 09:30:40

+0

我的文件有值我不知道它的序号或不是我的客户说它的序号,并告诉我,“如果你想找到实际的日期只是格式单元格在Excel中的给定值,那时我得到这个值“@MartijnPieters – Krish 2015-04-01 09:39:40

回答

10

在1900/01/01 Excel中的偏移量;增加的天数为timedelta:

from datetime import date, timedelta 

def from_excel_ordinal(ordinal, _epoch=date(1900, 1, 1)): 
    if ordinal > 59: 
     ordinal -= 1 # Excel leap year bug, 1900 is not a leap year! 
    return _epoch + timedelta(days=ordinal - 1) # epoch is day 1 

我不得不调整由的依次为1900年2月28日之后的任何日期; Excel从Lotus 1-2-3继承了leap year bug,并将1900作为闰年。上述代码为5960返回date(1900, 2, 28)以解决此问题。

+0

这是完美的,非常感谢你@Martijn Pieters – Krish 2015-04-01 09:47:09

+0

@Krish:这个bug被Joel Spolsky推广:[My First BillG Review](http://www.joelonsoftware.com/items/2006/06/16.html) – jfs 2015-04-02 20:07:45

+0

你确定这个时代不是1899年12月31日? datetime(1899,12,31)+ timedelta(ordinal - (ordinal> 59))' – jfs 2015-04-02 20:20:35

2
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) 

上面的答案对于日期值来说很好,但是在这里我扩展了上面的解决方案以包含时间并返回datetime值。

相关问题