programing

지정된 서수(Excel에서)를 날짜로 변환하는 방법

powerit 2023. 4. 23. 11:32
반응형

지정된 서수(Excel에서)를 날짜로 변환하는 방법

값 38142는 python을 사용하여 날짜 형식으로 변환해야 합니다.이 숫자를 excel로 사용하여 우클릭 및 포맷 셀을 실행하면 값이 2004년 4월 6일로 변환되어 python을 사용하여 동일한 결과가 필요합니다.어떻게 하면 좋을까요?

Excel의 오프셋은 1900/01/01 이후의 일수입니다.11900년 1월 1일이므로 timedelta로서 일수를 1899/12/31에 추가합니다.

from datetime import datetime, timedelta

def from_excel_ordinal(ordinal: float, _epoch0=datetime(1899, 12, 31)) -> datetime:
    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 이후의 날짜에는 서수를 하루까지 조정해야 합니다.Excel은 Lotus 1-2-3에서 윤년 버그를 상속받아 1900을 윤년으로 취급하고 있습니다.위의 코드가 반환됩니다.datetime(1900, 2, 28, 0, 0)쌍방에게59그리고.60이를 수정하려면 [59.0 ~61.0] 범위의 분수 값이 모두 당일 00:00:00.0 ~23:59:59.99999 사이의 시간이 됩니다.

위는 시간을 나타내는 분수를 가진 시리얼도 지원하지만 Excel은 마이크로초를 지원하지 않기 때문에 드롭됩니다.

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)

위의 답변은 날짜 값만으로 충분하지만, 여기서는 시간을 포함하도록 위의 솔루션을 확장하고 날짜 값도 반환합니다.

다음 사항을 제안합니다.

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 에서 가져옵니다.

이 질문은 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

각 열(열로 따옴표 포함)을 하나의 파라미터로 입력해야 합니다.이러한 파라미터는 대부분 개선될 수 있습니다(예를 들어 입력되는 열 리스트).또한 원본 df의 복사본을 반환합니다(원본을 변경하지 않음).

그리고, 이것에 의해서 어느 정도 영감을 얻었다(https://gist.github.com/oag335/9959241)).

만약 당신이 판다와 함께 일하고 있다면 이것은 유용할 것이다.

    import xlrd
    import datetime as dt
    
    def from_excel_datetime(x):
        return dt.datetime(*xlrd.xldate_as_tuple(x, datemode=0))
    
    df['date'] = df.excel_date.map(from_excel_datetime)

날짜가 4년 늦어질 것 같으면 date mode 1로 시도해보세요.

: date mode: 0: 1900 베이스, 1: 1904 베이스.

언급URL : https://stackoverflow.com/questions/29387137/how-to-convert-a-given-ordinal-number-from-excel-to-a-date

반응형