-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement custom XmlDateTime converter which keeps full precision of …
…fractional seconds
- Loading branch information
1 parent
3e15fa3
commit f69ec19
Showing
2 changed files
with
103 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
from typing import Any, Optional | ||
|
||
from xsdata.formats.converter import Converter | ||
from xsdata.models.datatype import XmlDateTime | ||
from xsdata.utils.dates import format_date, format_offset | ||
|
||
|
||
def custom_format_time( | ||
hour: int, minute: int, second: int, fractional_second: int | ||
) -> str: | ||
"""Serializes a time according to ISO 8601. | ||
Args: | ||
hour (int): The hour to serialize | ||
minute (int): The minute to serialize | ||
second (int): The second to serialize | ||
fractional_second (int): The fractional second to serialize. Can be either nano- micro- or milliseconds. | ||
Returns: | ||
str: The time formatted according to ISO 8601 (example: 14:14:33.000) | ||
""" | ||
microsecond, nano = divmod(fractional_second, 1000) | ||
if nano: | ||
return f"{hour:02d}:{minute:02d}:{second:02d}.{fractional_second:09d}" | ||
|
||
milli, micro = divmod(microsecond, 1000) | ||
if micro: | ||
return f"{hour:02d}:{minute:02d}:{second:02d}.{microsecond:06d}" | ||
|
||
return f"{hour:02d}:{minute:02d}:{second:02d}.{milli:03d}" | ||
|
||
|
||
class FullPrecisionXmlDateTimeConverter(Converter): | ||
"""Override the default XmlDateTimeConverter to preserve full precision when serializing datetimes | ||
Args: | ||
Converter (xsdata.formats.converter.Converter): Abstract converter class | ||
""" | ||
|
||
def deserialize(self, value: Any, **kwargs: Any) -> Any: | ||
return XmlDateTime.from_string(value) | ||
|
||
def serialize(self, value: Any, **kwargs: Any) -> Optional[str]: | ||
if isinstance(value, XmlDateTime): | ||
return "{}T{}{}".format( | ||
format_date(value.year, value.month, value.day), | ||
custom_format_time( | ||
value.hour, value.minute, value.second, value.fractional_second | ||
), | ||
format_offset(value.offset), | ||
) |