2009-07-10 34 views
44

Làm cách nào để chuyển đổi một ngày Excel (theo định dạng số) thành một ngày thích hợp bằng Python?Làm cách nào để đọc một ngày ở định dạng Excel bằng Python?

+0

Xin làm rõ: đưa ra một ví dụ về "dữ liệu Excel (trong một định dạng số) " –

+5

Trong nội bộ, Excel lưu trữ ngày tháng dưới dạng số động và bạn có thể phân biệt với các số" bình thường "chỉ bằng định dạng ô. –

+1

@Roberto Liffredo, vâng tôi biết rằng Excel đã lưu ngày tháng dưới dạng số động, tôi cần chuyển đổi chúng thành một ngày thích hợp và đó là lý do tại sao tôi hỏi câu hỏi này. @eliben, vui lòng xem nhận xét của Roberto – Grzenio

Trả lời

62

Bạn có thể sử dụng xlrd.

Từ số documentation, bạn có thể đọc ngày đó luôn được lưu dưới dạng số; tuy nhiên, bạn có thể sử dụng xldate_as_tuple để chuyển đổi thành ngày python.

Lưu ý: phiên bản trên PyPI có vẻ cập nhật hơn so với phiên bản có sẵn trên trang web của xlrd.

+0

@Roberto: cảm ơn lời nhắc nhở về trang web. –

24

Sau khi thử nghiệm và một vài ngày chờ phản hồi, tôi sẽ svn-cam kết toàn bộ chức năng mới sau đây trong mô-đun xldate xlrd ... lưu ý rằng nó sẽ không có sẵn cho các diehards vẫn chạy Python 2.1 hoặc 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) 
     ) 
+2

Xin chào @JohnMachin xin lỗi vì đã hồi sinh một chuỗi cũ nhưng bạn đã cam kết điều này. Tôi đang trên Ubuntu và python 2,7 và nó không có trong phiên bản tôi đang sử dụng. –

+2

Hàm 'xldate_as_datetime' được thêm vào mô-đun' xldate' như xlrd phiên bản 0.9.3 (được phát hành cho PyPI vào tháng 4 năm 2014). –

+0

'xldate_as_datetime' là một lựa chọn sạch hơn nhiều so với' xldate_as_tuple' trong quan điểm của tôi – Paco

21

Đây là trần-knuckle không dây an toàn sử dụng-at-riêng có nguy cơ phiên bản:

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) 
     ) 
+4

Đối với ngày Excel dựa trên 1900, điều này sẽ cung cấp 'datetime' không chính xác cho các ngày Excel trước ngày 1 tháng 3 năm 1900. Điều này là do lỗi trong Excel (không chính xác) nghĩ rằng năm 1900 là một năm nhuận. Xem [Bài viết Microsoft KB] (http://support.microsoft.com/kb/214326) – Ben

+2

Và hơn nữa cho giả định rất phi khoa học giống như khoa học rằng vì một lý do nào đó, sự bắt đầu của năm vào năm 1900 rơi vào 1 Như thể đó là thời Trung cổ và chúng ta không hiểu khái niệm 0; chúc mừng Microsoft. – AER

0

Đối nhanh chóng và dơ bẩn:

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

Vui lòng tham khảo liên kết này : Reading date as a string not float from excel using python xlrd

nó làm việc cho tôi:

trong bức ảnh này liên kết có:

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 
+2

thx để sao chép câu trả lời của tôi;) – jojo

+0

tôi hy vọng tôi đã không làm điều gì đó sai ở đây, tôi chỉ muốn đưa ra hướng để trả lời đúng ở đây. –

+0

Đừng lo! Nó có thể đã được nhiều hơn đủ để đặt một liên kết đến câu hỏi trùng lặp như một bình luận về câu hỏi này, nhưng đặt nó như là một câu trả lời là, ít nhất là cho tôi, tốt là tốt. – jojo

17

xlrd.xldate_as_tuple là tốt đẹp, nhưng có xlrd.xldate.xldate_as_datetime có thể chuyển đổi để datetime là tốt.

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

Kết hợp bài đăng của người đã cho tôi ngày và thời gian chuyển đổi excel. Tôi đã trở lại nó như là một chuỗi

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") 
-1

Khi chuyển đổi một tập tin Excel CSV ngày/thời gian tế bào trông như thế này:

foo, 2016/03/16 10:38, quầy bar,

để chuyển đổi các giá trị văn bản datetime để đối tượng python datetime làm điều này:

from datetime import datetime 

date_object = datetime.strptime('3/16/2016 10:38', '%m/%d/%Y %H:%M') # excel format (CSV file) 

in date_object sẽ trở lại 2005-06-01 13:33:00

+0

OP muốn câu trả lời cho xlrd, vì xlrd trả về trong phao –

1

Trong trường hợp bạn đang sử dụng gấu trúc và read_excel của bạn đọc trong Ngày được định dạng dưới dạng số Excel không đúng và cần khôi phục lại những ngày thực sau ...

Các lambda function áp dụng trên cột sử dụng để phục hồi xlrd ngày trở lại

import xlrd 
df['possible_intdate'] = df['possible_intdate'].apply(lambda s: xlrd.xldate.xldate_as_datetime(s, 0)) 


>> df['possible_intdate'] 

    dtype('<M8[ns]') 
0

Dự kiến ​​tình hình

# Wrong output from cell_values() 
42884.0 

# Expected output 
2017-5-29 

Ví dụ: Hãy cell_values ​​(2,2) từ số tờ sẽ là ngày được nhắm mục tiêu

Nhận các biến cần thiết như sau

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

sheet = workbook.sheet_by_index(0) 

wrongValue = sheet.cell_value(2,2) 

Và tận dụng xldate_as_tuple

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

Đó là giải pháp của tôi

Các vấn đề liên quan