Skip to content

Commit

Permalink
fix: ods export/import for datetime and time values
Browse files Browse the repository at this point in the history
  • Loading branch information
pascalfree committed Jul 13, 2024
1 parent 1975024 commit d3f6857
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 3 deletions.
6 changes: 6 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# History

## Unreleased

### Bugfixes

- Fix time and datetime export in ODS format (#595).

## 3.6.1 (2024-04-04)

### Bugfixes
Expand Down
10 changes: 7 additions & 3 deletions src/tablib/formats/_ods.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,11 @@ def convert_date(val):
return convert_date(date_value)
if value_type == 'time':
time_value = cell.getAttribute('timevalue')
return dt.datetime.strptime(time_value, "%H:%M:%S").time()
try:
return dt.datetime.strptime(time_value, "PT%HH%MM%SS").time()
except ValueError:
# backwards compatibility for times exported with older tablib versions
return dt.datetime.strptime(time_value, "%H:%M:%S").time()
if value_type == 'boolean':
bool_value = cell.getAttribute('booleanvalue')
return bool_value == 'true'
Expand Down Expand Up @@ -158,12 +162,12 @@ def dset_sheet(cls, dataset, ws):
cell = table.TableCell(valuetype="float", value=col)
elif isinstance(col, dt.datetime):
cell = table.TableCell(
valuetype="date", value=col.strftime('%Y-%m-%dT%H:%M:%S')
valuetype="date", datevalue=col.strftime('%Y-%m-%dT%H:%M:%S')
)
elif isinstance(col, dt.date):
cell = table.TableCell(valuetype="date", datevalue=col.strftime('%Y-%m-%d'))
elif isinstance(col, dt.time):
cell = table.TableCell(valuetype="time", timevalue=col.strftime('%H:%M:%S'))
cell = table.TableCell(valuetype="time", timevalue=col.strftime('PT%HH%MM%SS'))
elif col is None:
cell = table.TableCell(valuetype="void")
else:
Expand Down
Binary file modified tests/files/book.ods
Binary file not shown.
22 changes: 22 additions & 0 deletions tests/test_tablib.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import doctest
import json
import pickle
import re
import tempfile
import unittest
from decimal import Decimal
Expand All @@ -13,6 +14,7 @@
from uuid import uuid4

import xlrd
from odf import opendocument, table
from openpyxl.reader.excel import load_workbook

import tablib
Expand Down Expand Up @@ -1214,6 +1216,26 @@ def test_ods_unknown_value_type(self):
dataset = tablib.Dataset().load(fh, 'ods')
self.assertEqual(dataset.pop(), ('abcd',))

def test_ods_export_dates(self):
"""test against odf specification"""
date = dt.date(2019, 10, 4)
date_time = dt.datetime(2019, 10, 4, 12, 30, 8)
time = dt.time(14, 30)
data.append((date, time, date_time))
data.headers = ('date', 'time', 'date/time')
_ods = data.ods
ods_book = opendocument.load(BytesIO(_ods))
cells = ods_book.spreadsheet.getElementsByType(table.TableRow)[1].childNodes
# date value
self.assertEqual(cells[0].getAttribute('datevalue'), '2019-10-04')
# time value
duration_exp = re.compile(r"^P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?"
r"(?:T(?:(\d+)H)?(?:(\d+)M)?(?:([\d.]+)S)?)?$")
duration = duration_exp.match(cells[1].getAttribute('timevalue')).groups()
self.assertListEqual([0, 0, 0, 14, 30, 0], [int(v or 0) for v in duration])
# datetime value
self.assertEqual(cells[2].getAttribute('datevalue'), '2019-10-04T12:30:08')


class XLSTests(BaseTestCase):
def test_xls_format_detect(self):
Expand Down

0 comments on commit d3f6857

Please sign in to comment.