Skip to content

Instantly share code, notes, and snippets.

@chancyk
Last active June 1, 2017 17:34
Show Gist options
  • Save chancyk/48924ba3b2deff342cfc53140fb1179f to your computer and use it in GitHub Desktop.
Save chancyk/48924ba3b2deff342cfc53140fb1179f to your computer and use it in GitHub Desktop.
Convert an ISO8601 date to the Excel date representation.
from datetime import datetime, date
from dateutil.parser import parse
class ExcelDateException(Exception):
pass
def to_excel_date(iso_date):
"""Convert a date to the Excel representation of a date
which is the inclusive range of days since 1900-01-01.
Time values parsable by `dateutil` will be truncated to a date.
Excel handles times by dividing the time as seconds by the
number of seconds in a day, and this fraction is included
as the fractional-part of the number of days. For instance:
2017-01-01 == 42736
2017-01-01 1:35:01 == 42736.0659837963
The fractional-part calculation is not performed by this function.
"""
date = parse(iso_date).date()
delta = date - parse('1900-01-01').date()
if delta.days == 0:
excel_date = 1
elif delta.days > 0:
# We need to add 2 days to the delta since the datetime
# subtraction is not inclusive.
excel_date = delta.days + 2
else:
raise ExcelDateException("Excel only converts dates on or after 1900-01-01.")
return excel_date
def assetRaises(exception, fn, *args):
failedToRaise = False
try:
fn(*args)
except Exception as e:
if not type(e) is exception:
failedToRaise = True
finally:
if failedToRaise:
raise Exception("Expected `%s` to raise %s." % (fn.__name__, exception.__name__))
assert to_excel_date('2017-01-01') == 42736
assert to_excel_date('2017-01-01 1:35') == 42736
assert to_excel_date('1999-12-31') == 36525
assetRaises(ExcelDateException, to_excel_date, '1899-01-01')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment