Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: xlrd discerning dates from floats

I wanted to import a file containing text, numbers and dates using xlrd on Python.

I tried something like:

if "/" in worksheet.cell_value:
    do_this
else:
    do_that  

But that was of no use as I latter discovered dates are stored as floats, not strings. To convert them to datetime type I did:

try:
    get_row = str(datetime.datetime(*xlrd.xldate_as_tuple(worksheet.cell_value(i, col - 1), workbook.datemode)))
except:
    get_row = unicode(worksheet.cell_value(i, col - 1))

I have an exception in place for when the cell contains text. Now i want to get the numbers as numbers and the dates as dates, because right now all numbers are converted to dates.

Any ideas?

like image 545
Antoni4040 Avatar asked Jul 24 '13 07:07

Antoni4040


2 Answers

I think you could make this much simpler by making more use of the tools available in xlrd:

cell_type = worksheet.cell_type(row - 1, i)
cell_value = worksheet.cell_value(row - 1, i)

if cell_type == xlrd.XL_CELL_DATE:
    # Returns a tuple.
    dt_tuple = xlrd.xldate_as_tuple(cell_value, workbook.datemode)
    # Create datetime object from this tuple.
    get_col = datetime.datetime(
        dt_tuple[0], dt_tuple[1], dt_tuple[2], 
        dt_tuple[3], dt_tuple[4], dt_tuple[5]
    )
elif cell_type == xlrd.XL_CELL_NUMBER:
    get_col = int(cell_value)
else:
    get_col = unicode(cell_value)
like image 101
chewynougat Avatar answered Oct 26 '22 05:10

chewynougat


Well, never mind, I found a solution and here it is!

try:
    cell = worksheet.cell(row - 1, i)
    if cell.ctype == xlrd.XL_CELL_DATE:
        date = datetime.datetime(1899, 12, 30)
        get_ = datetime.timedelta(int(worksheet.cell_value(row - 1, i)))
        get_col2 = str(date + get_)[:10]
        d = datetime.datetime.strptime(get_col2, '%Y-%m-%d')
        get_col = d.strftime('%d-%m-%Y')
    else:
        get_col = unicode(int(worksheet.cell_value(row - 1, i))) 
except:
    get_col = unicode(worksheet.cell_value(row - 1, i))

A bit of explanation: it turns out that with xlrd you can actually check the type of a cell and check if it's a date or not. Also, Excel seems to have a strange way to save daytimes. It saves them as floats (left part for days, right part for hours) and then it takes a specific date (1899, 12, 30, seems to work OK) and adds the days and hours from the float to create the date. So, to create the date that I wanted, I just added them them and kept only the 10 first letters ([:10]) to get rid of the hours(00.00.00 or something...). I also changed the order of days_months-years because in Greece we use a different order. Finally, this code also checks if it can convert a number to an integer(I don't want any floats to show at my program...) and if everything fails, it just uses the cell as it is(in cases there are strings in the cells...). I hope that you find that useful, I think there are other threads that say that this is impossible or something...

like image 36
Antoni4040 Avatar answered Oct 26 '22 04:10

Antoni4040