Comment puis-je lire une date en format Excel en Python?
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.
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)
)
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)
)
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)
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
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]')
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
rapide et sale":
year, month, day, hour, minute, second = xlrd.xldate_as_tuple(excelDate, wb.datemode)
whatYouWant = str(month)+'/'+str(day)+'/'+str(year)
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")
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")
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