Skip to content

Commit be412eb

Browse files
committed
ODSReader: Use datetime.fromisoformat to parse date values in .ods
(this method is new in Python 3.7, so use a backport for earlier versions)
1 parent 58b031a commit be412eb

File tree

4 files changed

+18
-11
lines changed

4 files changed

+18
-11
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
88

99
### Fixed
1010

11+
- Fix parsing number formatting from .ods files https://github.com/OpenDataServices/flatten-tool/pull/373
12+
1113
## [0.15.3] - 2020-02-23
1214

15+
### Fixed
16+
1317
- use-titles: Use $ref'erring title if available https://github.com/OpenDataServices/flatten-tool/pull/368
1418
- create-template --no-deprecated-fields: Did not work if deprecated element at same level as a $ref https://github.com/OpenDataServices/flatten-tool/issues/185#issuecomment-719587348
1519

flattentool/ODSReader.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,18 @@
1515
# Thanks to grt for the fixes
1616
# https://github.com/marcoconti83/read-ods-with-odfpy
1717

18-
import re
1918
from collections import OrderedDict
2019
from datetime import datetime
2120

21+
import backports.datetime_fromisoformat
2222
import odf.opendocument
2323
from odf.table import Table, TableCell, TableRow
2424

2525

26+
# Backport for datetime.fromisoformat, which is new in Python 3.7
27+
backports.datetime_fromisoformat.MonkeyPatch.patch_fromisoformat()
28+
29+
2630
# http://stackoverflow.com/a/4544699/1846474
2731
class GrowingList(list):
2832
def __setitem__(self, index, value):
@@ -86,14 +90,12 @@ def readSheet(self, sheet):
8690
"date-value",
8791
)
8892
)
89-
# Add UTC timezone to naive datetime strings
90-
if re.match(
91-
r"^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d$", date_value
92-
):
93-
date_value += "Z"
94-
elif re.match(r"^\d{4}-\d\d-\d\d$", date_value):
95-
datetime.strptime(date_value, "%Y-%m-%d").isoformat()
96-
arrCells[count] = date_value
93+
# fromisoformat assumes microseconds appear as 3 or
94+
# 6 digits, whereas ods drops trailing 0s, so can
95+
# have 1-6 digits, so pad some extra 0s
96+
if "." in date_value:
97+
date_value = date_value.ljust(26, "0")
98+
arrCells[count] = datetime.fromisoformat(date_value)
9799
else:
98100
arrCells[count] = str(cell)
99101
count += 1

flattentool/tests/test_input_SpreadsheetInput.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,8 @@ def test_ods_input_types(self):
211211
{
212212
"colInt": 1,
213213
"colFloat": 1.2,
214-
"colDate": "2020-03-05",
215-
"colDateTime": "2020-02-07T16:41:00Z",
214+
"colDate": datetime.datetime(2020, 3, 5),
215+
"colDateTime": datetime.datetime(2020, 2, 7, 16, 41),
216216
}
217217
]
218218
assert type(list(odsinput.get_sheet_lines("main"))[0]["colInt"]) == int

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def run(self):
3535
"xmltodict",
3636
"lxml",
3737
"odfpy",
38+
"backports-datetime-fromisoformat",
3839
]
3940

4041
setup(

0 commit comments

Comments
 (0)