Как преобразовать заданный порядковый номер (из Excel) в дату

У меня есть значение 38142 Мне нужно преобразовать его в формат даты с помощью python. если использовать этот номер в excel и сделать ячейку правого клика и форматирования в это время, значение будет преобразовано в 04/06/2004, и мне нужен тот же результат с использованием python. Как я могу достичь этого

Ответ 1

Смещение в Excel - это количество дней с 1900/01/01, где 1 - первое января 1900 года, поэтому добавьте количество дней в качестве временной разницы к 1899/12/31:

from datetime import datetime, timedelta

def from_excel_ordinal(ordinal, _epoch0=datetime(1899, 12, 31)):
    if ordinal > 59:
        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 чтобы исправить это.

Выше также поддерживаются сериалы с дробью для представления времени, но поскольку Excel не поддерживает микросекунды, они отбрасываются.

Ответ 2

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)

Вышеуказанный ответ подходит только для значения даты, но здесь я предлагаю вышеописанное решение включить время и вернуть значения даты и времени.

Ответ 3

Я бы порекомендовал следующее:

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

Ответ 4

Я пришел к этому вопросу, пытаясь сделать то же самое выше, но для целых столбцов в пределах df. Я сделал эту функцию, которая сделала это для меня:

from datetime import datetime
import copy as cp

def xlDateConv(df, *cols):      
    dt = []
    fin = cp.deepcopy(df)
    for col in [*cols]:
        for i in fin[col]:
            x = datetime.fromordinal(datetime(1900, 1, 1).toordinal() + fin[col][i])
            dt.append(x)

        fin[col] = dt
        dt = []
    return fin

Обратите внимание, что вам нужно ввести каждый столбец, заключенный в кавычки (в виде строки), в качестве одного параметра, который, скорее всего, можно улучшить (например, список столбцов в качестве входных данных). Кроме того, он возвращает копию оригинального df (не меняет оригинал).

Кстати, скопировал код ниже

datetime.fromordinal(datetime (1900, 1, 1).toordinal() + fin [col] [i])

из другого ответа, найдете его и подтвердите здесь.

Я новичок в этом, поэтому, пожалуйста, комментируйте и улучшайте его, как хотите :)