Skip to content

Commit

Permalink
return datetime.time directly
Browse files Browse the repository at this point in the history
  • Loading branch information
mzuzek committed Oct 3, 2023
1 parent 069c93b commit bd4c893
Showing 1 changed file with 16 additions and 7 deletions.
23 changes: 16 additions & 7 deletions pandas/io/excel/_odfreader.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import datetime
import re
from typing import (
TYPE_CHECKING,
Expand Down Expand Up @@ -183,19 +184,27 @@ def _get_column_repeat(self, cell) -> int:

return int(cell.attributes.get((TABLENS, "number-columns-repeated"), 1))

def _parse_odf_time(self, value: str) -> pd.Timestamp:
def _parse_odf_time(self, value: str) -> datetime.time:
"""
Helper function to convert ODF variant of ISO 8601 formatted duration
"PnYnMnDTnHnMnS" - see https://www.w3.org/TR/xmlschema-2/#duration
"""
parts = re.match(r"^\s*PT\s*(\d+)\s*H\s*(\d+)\s*M\s*(\d+(\.\d+)?)\s*S$", value)
if parts is None:
raise ValueError(f"Failed to parse ODF time value: {value}")
h, m, s = parts.group(1, 2, 3)
# ignore date part from some representations as both pd.Timestamp
# and datetime.time restrict hour values to 0..23
h = str(int(h) % 24)
return pd.Timestamp(f"{h}:{m}:{s}")
hours, minutes, seconds, _, second_part = parts.group(*range(1, 6))
if second_part is None:
microseconds = 0
else:
microseconds = int(int(second_part) * pow(10, 6 - len(second_part)))
return datetime.time(
# ignore date part from some representations
# and datetime.time restrict hour values to 0..23
hour=int(hours) % 24,
minute=int(minutes),
second=int(seconds),
microsecond=microseconds,
)

def _get_cell_value(self, cell) -> Scalar | NaTType:
from odf.namespaces import OFFICENS
Expand Down Expand Up @@ -232,7 +241,7 @@ def _get_cell_value(self, cell) -> Scalar | NaTType:
cell_value = cell.attributes.get((OFFICENS, "time-value"))
stamp = self._parse_odf_time(str(cell_value))
# cast needed here because Scalar doesn't include datetime.time
return cast(Scalar, stamp.time())
return cast(Scalar, stamp)
else:
self.close()
raise ValueError(f"Unrecognized type {cell_type}")
Expand Down

0 comments on commit bd4c893

Please sign in to comment.