web-dev-qa-db-ja.com

特定の序数(Excelから)を日付に変換する方法

値38142があります。Pythonを使用して日付形式に変換する必要があります。 Excelでこの数値を使用し、右クリックしてセルをフォーマットすると、値は2004年4月6日に変換され、Pythonを使用して同じ結果が必要になります。どうすればこれを達成できますか

24
Krish

Excelでのオフセットは、1900/01/01からの日数であり、_1_は1900年1月の最初であるため、日数をタイムデルタとして1899/12/31に追加します。

_from datetime import datetime, timedelta

def from_Excel_ordinal(ordinal, _Epoch0=datetime(1899, 12, 31)):
    if ordinal >= 60:
        ordinal -= 1  # Excel leap year bug, 1900 is not a leap year!
    return (_Epoch0 + timedelta(days=ordinal)).replace(microsecond=0)
_

1900/02/28以降の日付については、序数を1日調整する必要があります。 ExcelはLotus1-2-3から うるう年バグ を継承し、1900をうるう年として扱います。上記のコードは、これを修正するために_59_と_60_の両方に対してdatetime(1900, 2, 28, 0, 0)を返し、[59.0〜61.0)の範囲の小数値はすべて00:00:00.0の間の時間です。その日の23:59:59.999999。

上記は、時間を表す小数部のシリアルもサポートしていますが、Excelはマイクロ秒をサポートしていないため、それらは削除されます。

29
Martijn Pieters
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)

上記の答えは日付値だけで問題ありませんが、ここでは上記のソリューションを拡張して時刻を含め、日時値も返します。

4
David

私は次のことをお勧めします:

import pandas as pd

def convert_Excel_time(Excel_time):

    return pd.to_datetime('1900-01-01') + pd.to_timedelta(Excel_time,'D')

または

import datetime

def xldate_to_datetime(xldate):
    temp = datetime.datetime(1900, 1, 1)
    delta = datetime.timedelta(days=xldate)
    return temp+delta

https://Gist.github.com/oag335/9959241 から取得

0
Michael D

上記と同じことをしようとしたときに、この質問に行き着きましたが、df内の列全体に対してです。私はこの関数を作りました、それは私のためにそれをしました:

import pandas as pd    
from datetime import datetime, timedelta
import copy as cp

def xlDateConv(df, *cols):      
    tempDt = []
    fin = cp.deepcopy(df)
    for col in [*cols]:
        for i in range(len(fin[col])):
            tempDate = datetime(1900, 1, 1)
            delta = timedelta(float(fin[col][i]))
            tempDt.append(pd.to_datetime(tempDate+delta))

        fin[col] = tempDt
        tempDt = []
    return fin

引用符で囲まれた(文字列として)各列を1つのパラメーターとして入力する必要があることに注意してください。これは、おそらく改善される可能性があります(たとえば、入力としての列のリスト)。また、元のdfのコピーを返します(元のdfは変更しません)。

ところで、これに部分的に触発されました( https://Gist.github.com/oag335/9959241 )。

0
Alan