2015-04-01 6 views
6

Ho un valore 38142 Ho bisogno di convertirlo in formato data usando python. se si utilizza questo numero in Excel e si fa clic con il tasto destro del mouse e si formatta la cella in quel momento il valore sarà convertito in 04/06/2004 e ho bisogno dello stesso risultato usando python. Come posso ottenere questoCome convertire un dato numero ordinale (da Excel) ad una data

+0

Questo è un ordinale strano; sei sicuro che il 04/06/2004 sia corretto? Se il valore 38142 corrisponde a * giorni *, questo sarebbe un offset dal 1993/12/25 o dal 1993/10/27 a seconda di ciò che interpreti come il mese. –

+0

[Formula per convertire la data in numero] (http://stackoverflow.com/q/19721416) suggerisce che dovrebbe essere un numero di giorni dal 1900/01/01, che è ciò che 'date.fromordinal()' fa. Ma a quel numero manca una cifra allora. –

+0

Il mio file ha il valore Non so il suo ordinale o no il mio cliente dice il suo ordinale e mi ha detto che "se vuoi trovare la data effettiva basta formattare la cella in Excel per il valore dato in quel momento sto ottenendo questo valore "@MartijnPieters – Krish

risposta

10

L'offset in Excel dal 1900/01/01; aggiungere il numero di giorni come un 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 

ho dovuto regolare il numero ordinale da per qualsiasi data dopo il 1900/02/28; Excel ha ereditato un leap year bug da Lotus 1-2-3 e considera 1900 come anno bisestile. Il codice sopra restituisce date(1900, 2, 28) per 59 e 60 per correggere ciò.

+0

Perfetto, Grazie mille @Martijn Pieters – Krish

+0

@Krish: il bug è reso popolare da Joel Spolsky: [My First BillG Review] (http://www.joelonsoftware.com/items/2006/06/16.html) – jfs

+0

Sei sicuro che l'epoca non è il 31 dicembre 1899? 'datetime (1899, 12, 31) + timedelta (ordinale - (ordinale> 59))' – jfs

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) 

La risposta di cui sopra va bene solo per un valore di data, ma qui ho estendere la soluzione di cui sopra per includere il tempo e tornare a valori datetime pure.

Problemi correlati