|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
| 3 | +import datetime |
3 | 4 | import re
|
4 | 5 | from typing import (
|
5 | 6 | TYPE_CHECKING,
|
@@ -183,19 +184,27 @@ def _get_column_repeat(self, cell) -> int:
|
183 | 184 |
|
184 | 185 | return int(cell.attributes.get((TABLENS, "number-columns-repeated"), 1))
|
185 | 186 |
|
186 |
| - def _parse_odf_time(self, value: str) -> pd.Timestamp: |
| 187 | + def _parse_odf_time(self, value: str) -> datetime.time: |
187 | 188 | """
|
188 | 189 | Helper function to convert ODF variant of ISO 8601 formatted duration
|
189 | 190 | "PnYnMnDTnHnMnS" - see https://www.w3.org/TR/xmlschema-2/#duration
|
190 | 191 | """
|
191 | 192 | parts = re.match(r"^\s*PT\s*(\d+)\s*H\s*(\d+)\s*M\s*(\d+(\.\d+)?)\s*S$", value)
|
192 | 193 | if parts is None:
|
193 | 194 | raise ValueError(f"Failed to parse ODF time value: {value}")
|
194 |
| - h, m, s = parts.group(1, 2, 3) |
195 |
| - # ignore date part from some representations as both pd.Timestamp |
196 |
| - # and datetime.time restrict hour values to 0..23 |
197 |
| - h = str(int(h) % 24) |
198 |
| - return pd.Timestamp(f"{h}:{m}:{s}") |
| 195 | + hours, minutes, seconds, _, second_part = parts.group(*range(1, 6)) |
| 196 | + if second_part is None: |
| 197 | + microseconds = 0 |
| 198 | + else: |
| 199 | + microseconds = int(int(second_part) * pow(10, 6 - len(second_part))) |
| 200 | + return datetime.time( |
| 201 | + # ignore date part from some representations |
| 202 | + # and datetime.time restrict hour values to 0..23 |
| 203 | + hour=int(hours) % 24, |
| 204 | + minute=int(minutes), |
| 205 | + second=int(seconds), |
| 206 | + microsecond=microseconds, |
| 207 | + ) |
199 | 208 |
|
200 | 209 | def _get_cell_value(self, cell) -> Scalar | NaTType:
|
201 | 210 | from odf.namespaces import OFFICENS
|
@@ -232,7 +241,7 @@ def _get_cell_value(self, cell) -> Scalar | NaTType:
|
232 | 241 | cell_value = cell.attributes.get((OFFICENS, "time-value"))
|
233 | 242 | stamp = self._parse_odf_time(str(cell_value))
|
234 | 243 | # cast needed here because Scalar doesn't include datetime.time
|
235 |
| - return cast(Scalar, stamp.time()) |
| 244 | + return cast(Scalar, stamp) |
236 | 245 | else:
|
237 | 246 | self.close()
|
238 | 247 | raise ValueError(f"Unrecognized type {cell_type}")
|
|
0 commit comments