web-dev-qa-db-ja.com

PythonでExcel形式の日付を読み取るにはどうすればよいですか?

PythonでExcelの日付(数値形式)を適切な日付に変換するにはどうすればよいですか?

51
Grzenio

xlrd を使用できます。

ドキュメント から、日付は常に数値として保存されていることがわかります。ただし、 xldate_as_Tuple python日付に変換します。

注:PyPIのバージョンは、xlrdのWebサイトで入手可能なバージョンよりも最新のようです。

67
rob

テストと数日後のフィードバックを待って、xlrdのxldateモジュールで次の新しい関数をsvn-commitします... Python 2.1または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
John Machin

これは、裸のナックルのシートベルトなしの自己使用リスクバージョンです:

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)
        )
25
John Machin

xlrd.xldate_as_Tupleはいいですが、xlrd.xldate.xldate_as_datetimeは、日時にも変換されます。

import xlrd
wb = xlrd.open_workbook(filename)
xlrd.xldate.xldate_as_datetime(41889, wb.datemode)
=> datetime.datetime(2014, 9, 7, 0, 0)
21
beardc

このリンクを参照してください: python xlrd を使用してExcelからフロートしない文字列として日付を読み取ります

それは私のために働いた:

ショットでは、このリンクがあります:

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
5
Snehal Parmar

予想される状況

# Wrong output from cell_values()
42884.0

# Expected output
2017-5-29

例:cell_values(2,2) fromシート番号が対象の日付になります

次のように必要な変数を取得します

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

sheet = workbook.sheet_by_index(0)

wrongValue = sheet.cell_value(2,2)

xldate_as_Tupleを利用します

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

それが私の解決策です

2
Edwardhk

pandasを使用していて、read_ExcelがExcelの数値として不適切にフォーマットされた日付を読み取り、実際の日付を復元する必要がある場合...

lambda function列に適用すると、xlrdを使用して日付を復元します

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
jetpackdata.com

Excelは、日付と時刻を1900-Jan-0以降の日数を表す数値として保存します。Pythonを使用して日付形式で日付を取得する場合は、以下に示すように、日列から2日を減算します。

日付= sheet.cell(1,0).value-2 // Pythonで

私のExcelの列1には、日付と上記のコマンドで日付値から2日を引いたものがあり、これはExcelシートにある日付と同じです

1
Ankush Bhatia

迅速で汚れた場合:

year, month, day, hour, minute, second = xlrd.xldate_as_Tuple(excelDate, wb.datemode)
whatYouWant = str(month)+'/'+str(day)+'/'+str(year)
0
Cmag

これは、@ houndedの改訂版です。私のコードは43705.591795706のような日付と時刻の両方を処理します

    import math
    import datetime


    def xldate_to_datetime(xldatetime): #something like 43705.6158241088

      tempDate = datetime.datetime(1899, 12, 31)
      (days, portion) = math.modf(xldatetime)

      deltaDays = datetime.timedelta(days=days)
      #changing the variable name in the edit
      secs = int(24 * 60 * 60 * portion)
      detlaSeconds = datetime.timedelta(seconds=secs)
      TheTime = (tempDate + deltaDays + detlaSeconds )
      return TheTime.strftime("%Y-%m-%d %H:%M:%S")


xldate_to_datetime(43705.6158241088)
# 2019-08-29 14:46:47
0
Dustin Sun

Excelファイルが別のコンピューター/人から来ている可能性があるため。書式設定が乱雑になる可能性があります。慎重に注意してください。

日付が入力 in DD/MM/YYYYまたはDD-MM-YYYY、ただし、ほとんどのExcelファイル格納済みそれらはMM/DD/YYYY(おそらくPCがen-us の代わりに en-gbまたはen-in)。

さらにいらいらしたのは、日付が13/MM/YYYYDD/MM/YYYYフォーマットはまだです。そのため、Excelファイル内にバリエーションがありました。

私が考え出した最も信頼できるソリューションは、各Excelファイルの日付列を手動でプレーンテキストに設定し、このコードを使用して解析することでした。

if date_str_from_Excel:
    try:
        return datetime.strptime(date_str_from_Excel, '%d/%m/%Y')
    except ValueError:
        print("Unable to parse date")
0
Nitin Nain

人々の投稿を組み合わせることで、Excel変換の日付と時刻がわかりました。文字列として返しました

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
hounded