Comment puis-je lire une date en format Excel en Python?

Comment puis-je convertir une date Excel (dans un format numérique) en une date correcte en Python?

49
demandé sur Grzenio 2009-07-10 12:41:45

11 réponses

vous pouvez utiliser xlrd .

à partir de sa documentation , vous pouvez lire que les dates sont toujours stockées sous forme de nombres; cependant, vous pouvez utiliser xldate_as_tuple pour la convertir en une date python.

Note: la version sur le PyPI semble plus à jour que celle disponible sur le site de xlrd.

65
répondu Roberto Liffredo 2009-07-10 08:53:44

après les tests et quelques jours d'attente de commentaires, je vais svn-commit la nouvelle fonction suivante dans le module xldate de xlrd ... notez qu'il ne sera pas disponible pour les diehards qui utilisent encore Python 2.1 ou 2.2.

##
# Convert an Excel number (presumed to represent a date, a datetime or a time) into
# a Python datetime.datetime
# @param xldate The Excel number
# @param datemode 0: 1900-based, 1: 1904-based.
# <br>WARNING: when using this function to
# interpret the contents of a workbook, you should pass in the Book.datemode
# attribute of that workbook. Whether
# the workbook has ever been anywhere near a Macintosh is irrelevant.
# @return a datetime.datetime object, to the nearest_second.
# <br>Special case: if 0.0 <= xldate < 1.0, it is assumed to represent a time;
# a datetime.time object will be returned.
# <br>Note: 1904-01-01 is not regarded as a valid date in the datemode 1 system; its "serial number"
# is zero.
# @throws XLDateNegative xldate < 0.00
# @throws XLDateAmbiguous The 1900 leap-year problem (datemode == 0 and 1.0 <= xldate < 61.0)
# @throws XLDateTooLarge Gregorian year 10000 or later
# @throws XLDateBadDatemode datemode arg is neither 0 nor 1
# @throws XLDateError Covers the 4 specific errors

def xldate_as_datetime(xldate, datemode):
    if datemode not in (0, 1):
        raise XLDateBadDatemode(datemode)
    if xldate == 0.00:
        return datetime.time(0, 0, 0)
    if xldate < 0.00:
        raise XLDateNegative(xldate)
    xldays = int(xldate)
    frac = xldate - xldays
    seconds = int(round(frac * 86400.0))
    assert 0 <= seconds <= 86400
    if seconds == 86400:
        seconds = 0
        xldays += 1
    if xldays >= _XLDAYS_TOO_LARGE[datemode]:
        raise XLDateTooLarge(xldate)

    if xldays == 0:
        # second = seconds % 60; minutes = seconds // 60
        minutes, second = divmod(seconds, 60)
        # minute = minutes % 60; hour    = minutes // 60
        hour, minute = divmod(minutes, 60)
        return datetime.time(hour, minute, second)

    if xldays < 61 and datemode == 0:
        raise XLDateAmbiguous(xldate)

    return (
        datetime.datetime.fromordinal(xldays + 693594 + 1462 * datemode)
        + datetime.timedelta(seconds=seconds)
        )
25
répondu John Machin 2009-07-10 13:29:51

Voici la version sans ceinture de sécurité à risques:

import datetime

def minimalist_xldate_as_datetime(xldate, datemode):
    # datemode: 0 for 1900-based, 1 for 1904-based
    return (
        datetime.datetime(1899, 12, 30)
        + datetime.timedelta(days=xldate + 1462 * datemode)
        )
22
répondu John Machin 2009-07-11 01:25:02

xlrd.xldate_as_tuple c'est bien, mais il y a xlrd.xldate.xldate_as_datetime qui se convertit aussi en datetime.

import xlrd
wb = xlrd.open_workbook(filename)
xlrd.xldate.xldate_as_datetime(41889, wb.datemode)
=> datetime.datetime(2014, 9, 7, 0, 0)
19
répondu beardc 2015-01-29 17:21:59

référez-vous à ce lien: date de lecture comme une chaîne de caractères non float à partir d'excel en utilisant python xlrd

il a travaillé pour moi:

dans le coup ce le lien est:

import datetime, xlrd
book = xlrd.open_workbook("myfile.xls")
sh = book.sheet_by_index(0)
a1 = sh.cell_value(rowx=0, colx=0)
a1_as_datetime = datetime.datetime(*xlrd.xldate_as_tuple(a1, book.datemode))
print 'datetime: %s' % a1_as_datetime
4
répondu Snehal Parmar 2017-05-23 12:17:58

Incase vous utilisez pandas et votre read_excel lit dans la Date formatée comme des nombres Excel incorrectement et ont besoin de récupérer les dates réelles derrière...

le lambda function appliqué sur la colonne utilise xlrd pour récupérer la date retour

import xlrd
df['possible_intdate'] = df['possible_intdate'].apply(lambda s: xlrd.xldate.xldate_as_datetime(s, 0))


>> df['possible_intdate']

   dtype('<M8[ns]')
1
répondu jetpackdata.com 2016-12-15 01:49:15

situation attendue

# Wrong output from cell_values()
42884.0

# Expected output
2017-5-29

exemple: soit cell_values (2,2) du numéro de feuille 0 sera la date ciblé

Obtenir les variables suivantes

workbook = xlrd.open_workbook("target.xlsx")

sheet = workbook.sheet_by_index(0)

wrongValue = sheet.cell_value(2,2)

et utiliser xldate_as_tuple

y, m, d, h, i, s = xlrd.xldate_as_tuple(wrongValue, workbook.datemode)
print("{0} - {1} - {2}".format(y, m, d))

C'est ma solution

1
répondu Edwardhk 2017-06-20 00:15:51

rapide et sale":

year, month, day, hour, minute, second = xlrd.xldate_as_tuple(excelDate, wb.datemode)
whatYouWant = str(month)+'/'+str(day)+'/'+str(year)
0
répondu Cmag 2014-06-10 03:35:15

une combinaison de peoples post m'a donné la date et l'heure pour la conversion excel. Je l'ai retourné comme une chaîne de caractères

def xldate_to_datetime(xldate):
  tempDate = datetime.datetime(1900, 1, 1)
  deltaDays = datetime.timedelta(days=int(xldate))
  secs = (int((xldate%1)*86400)-60)
  detlaSeconds = datetime.timedelta(seconds=secs)
  TheTime = (tempDate + deltaDays + detlaSeconds )
  return TheTime.strftime("%Y-%m-%d %H:%M:%S")
0
répondu hounded 2015-03-30 00:14:18

Puisqu'il y a une chance que vos fichiers excel proviennent de différents ordinateurs/personnes; il y a une chance que le formatage soit désordonné; alors soyez très prudent.

je viens d'importer des données de 50 excels impairs où les dates étaient entré dans DD/MM/YYYY ou DD-MM-YYYY , mais la plupart des fichiers Excel stockés eux comme MM/DD/YYYY (probablement parce que les PC ont été configurés avec en-us au lieu de en-gb ou en-in ).

encore plus irritant était le fait que les dates au-dessus de 13/MM/YYYY étaient dans le format DD/MM/YYYY encore. Il y avait donc des variations dans les fichiers Excel.

la solution la plus fiable que j'ai trouvée était de définir manuellement la colonne de Date sur chaque fichier excel pour être du texte simple -- puis utiliser ce code pour l'analyser:

if date_str_from_excel:
    try:
        return datetime.strptime(date_str_from_excel, '%d/%m/%Y')
    except ValueError:
        print("Unable to parse date")
0
répondu Nitin Nain 2018-08-07 11:05:55

lors de la conversion d'un fichier excel en CSV la cellule date/heure ressemble à ceci:

foo, 3/16/2016 10: 38, bar,

pour convertir la valeur du texte datetime en objet Python datetime faites ceci:

from datetime import datetime

date_object = datetime.strptime('3/16/2016 10:38', '%m/%d/%Y %H:%M')    # excel format (CSV file)

imprimer date_object sera de retour 2005-06-01 13:33:00

-1
répondu Gilbert 2016-03-16 11:49:23