xsdata icon indicating copy to clipboard operation
xsdata copied to clipboard

Full precision of XmlDateTime is not preserved

Open chrismostert opened this issue 1 year ago • 3 comments

We are currently running into an issue where we expect XmlDateTime values to be te same after a roundtrip (parsing the .xml file and then writing it back again). We would expect the following input to serialize back to the same input string:

from xsdata.models.datatype import XmlDateTime

input = "2023-11-23T19:38:38.000"
output = str(XmlDateTime.from_string(input))

Here the string representation (and the value in any eventual serialized .xml file) becomes 2023-11-23T19:38:38 while we would expect the XmlDateTime object to preserve the full precision of the time component, giving back 2023-11-23T19:38:38.000.

It seems that the fractional seconds are purposefully truncated, is there any reason that xsdata does this? We'd rather see that the full precision of the time is preserved, and commenting out the linked line of code results in the desired behaviour.

Could this be changed so that the franctional seconds are no longer truncated if they are zero? If this results in undesired behaviour elsewhere, then I could also see this being a toggle in for example the configuration for the XmlSerializer.

chrismostert avatar Jan 15 '24 09:01 chrismostert

xsdata was inspired from java's jaxb, I think that was default behaviour.

I ''l take a look on how easy it's to expose it as a serializer configuration option

tefra avatar Jan 15 '24 15:01 tefra

It seems that the fractional seconds are purposefully truncated, is there any reason that xsdata does this? We'd rather see that the full precision of the time is preserved, and commenting out the linked line of code results in the desired behaviour.

I have had my users complain about the exact oposite. The fractions actually being there while not intended. So maybe an explicit remove fractional would also be nice (now doing a replace on every instance).

skinkie avatar Jan 17 '24 00:01 skinkie

Cool so if I figure out how to the serializer config to reach the converters, we want 3 behaviors: always, never and non-zeros

tefra avatar Jan 18 '24 18:01 tefra

Most datetime parser support either approach, it's usually people who do some sort of manual parsing that need something like this, I guess.

In any way most libraries follow this pattern, if you want you can override the XmlDateTime converter to apply this logic

from xsdata.formats.converter import Converter, converter

class MyXmlDateTimeConverter(Converter):

    def deserialize(self, value: Any, **kwargs: Any) -> Any:
        return XmlDateTime.from_string(value)

    def serialize(self, value: Any, **kwargs: Any) -> str:
        if isinstance(value, XmlDateTime):
            return "whatever you want"


converter.register_converter(XmlDateTime, MyXmlDateTimeConverter())

tefra avatar Mar 09 '24 18:03 tefra

Can you put this snippet somewhere in the documentation?

skinkie avatar Mar 09 '24 18:03 skinkie

Can you put this snippet somewhere in the documentation?

Feel free to open a pr with the docs example

tefra avatar Mar 09 '24 18:03 tefra