I’ve written a script that changes values for a certain date in an excel sheet. When I create a new excel file using copy, it copies everything over correctly except for the year portion of the date. For example, it will go from 4/5/2012 to 4/5/2008. It appears that all dates go back four years. Here’s the code:
def exceledit():
#open excel sheet
import xlrd, xlwt, xlutils
import datetime
from xlutils.copy import copy
print 'Opening excel sheet...'
book = xlrd.open_workbook('test.xls', on_demand=True, formatting_info=True)
print 'Creating and editing new excel sheet...'
wbook = copy(book)
print 'Done creating new excel sheet'
sh = book.sheet_by_index(0)
#iterate through dates in excel sheet
for colnum in range(sh.ncols):
date = sh.cell_value(3, colnum+4)
#if xlrd finds a date
if date:
#grab date data
year, month, day, hour, minute, second = xlrd.xldate_as_tuple(date\
, book.datemode)
#if dates are within the month currently being edited
if month == 04:
#format excel date information to work with parkh dict
format = str(month) + "/" + str(day) + "/" + str(year)
print 'Editing ' + format
#clear cells to eliminate old information
wbook.get_sheet(0).write(6, colnum+6, "")
wbook.get_sheet(0).write(5, colnum+6, "")
wbook.get_sheet(0).write(7, colnum+6, "")
#iterate through hour segments for that day
for x in parkh[format]:
#if regular hours, insert in "HOURS" row
if x[0] == 'Park Hours':
wbook.get_sheet(0).write(6, colnum+6, x[1])
#if extra magic hours, insert in respective row
if x[0] == 'Extra Magic Hours':
#insert in morning row
if int(x[1][0:1]) in range(2,9):
wbook.get_sheet(0).write(5, colnum+6, x[1])
#insert in evening row
else:
wbook.get_sheet(0).write(7, colnum+6, x[1])
if month == 05:
break
print 'Done editing. Now saving...'
wbook.save('new.xls')
print 'new.xls saved'
Any idea why it might be changing the year? I haven’t seen anyone else have the same issue elsewhere.
You evidently have an input Excel file that is using the 1904 date system. Your immediate problem is that
xlutilsdoesn’t support copying these files correctly. Fortunately the fix is a one-liner and you can even do it yourself in your script after you have done the copy:This works for copying dates because
xlwtsupports writing the record that specifies what datemode is in use.WARNING Any new date values that you write into the file by using Worksheet.write() will NOT be written correctly, as
xlwtunfortunately ignores thedates_1904setting when convertingdatetime.dateanddatetime.datetimeobjects to the Excel magic floats.I have written and tested a fix which replaces the whole body of the
Row.__excel_date_dtmethod. It will be committed to the newxlwtrepository ongithubsoonish. In the meantime here is the code if you are in dire need:WARNING Trying to convert your file to the 1900 system by opening it in Excel, unticking the 1904 config item and saving the file DOESN’T WORK — dates will be 4 years out of whack.
What appears to work properly is this:
open the file in Excel, save it as
XML Spreadsheet 2003 (*.xml)…this format records dates in text format e.g.
1999-12-31T23:59:59.999open the XML file in a text editor, find the line that reads
<Date1904/>… yes, the XML is human-readable straight out of thebox … and delete it, then save the xml file
open the changed XML file in Excel, all your data and formatting
should be preserved, the only difference should be that the pesky
1904 box is not ticked anymore. You can then save it as an XLS file