Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

isotime.py parse_time method rounds 59.99999 to 60 causing ValueError #87

Open
RetliwG opened this issue Nov 17, 2023 · 0 comments
Open

Comments

@RetliwG
Copy link

RetliwG commented Nov 17, 2023

We are making a SOAP API request to SAP which occasionally obtains timestamps strings where seconds is 59 and milliseconds 9999999. This causes the parse_time method to give the following error:

File "/Users/my_user/.pyenv/versions/3.10.10/envs/virt_python3/lib/python3.10/site-packages/isodate/isotime.py", line 134, in parse_time
return time(int(groups['hour']), int(groups['minute']),
ValueError: second must be in 0..59

Adding the following print lines to the isotime.py script (lines 125 - 136):

if 'second' in groups: # round to microseconds if fractional seconds are more precise print(f"groups['second'] = {groups['second']}") second = Decimal(groups['second']).quantize(Decimal('.000001')) print(f"second = {second}") microsecond = (second - int(second)) * int(1e6) # int(...) ... no rounding # to_integral() ... rounding print(f"int(groups['hour'] = {int(groups['hour'])}, int(groups['minute']) = {int(groups['minute'])}, int(second) = {int(second)}, int(microsecond.to_integral()) = {int(microsecond.to_integral())}") return time(int(groups['hour']), int(groups['minute']), int(second), int(microsecond.to_integral()), tzinfo)

We get the following printed values when calling SOAP API:
groups['second'] = 18.770246 second = 18.770246 int(groups['hour'] = 16, int(groups['minute']) = 19, int(second) = 18, int(microsecond.to_integral()) = 770246 groups['second'] = 18.770246 second = 18.770246 int(groups['hour'] = 16, int(groups['minute']) = 19, int(second) = 18, int(microsecond.to_integral()) = 770246 groups['second'] = 00 second = 0.000000 int(groups['hour'] = 14, int(groups['minute']) = 0, int(second) = 0, int(microsecond.to_integral()) = 0 groups['second'] = 59.9999999 second = 60.000000 int(groups['hour'] = 23, int(groups['minute']) = 59, int(second) = 60, int(microsecond.to_integral()) = 0 Error during xml -> python translation Traceback (most recent call last): File "/Users/my_user/.pyenv/versions/3.10.10/envs/virt_python3/lib/python3.10/site-packages/zeep/xsd/types/simple.py", line 79, in parse_xmlelement return self.pythonvalue(xmlelement.text) File "/Users/my_user/.pyenv/versions/3.10.10/envs/virt_python3/lib/python3.10/site-packages/zeep/xsd/types/builtins.py", line 44, in _wrapper return func(self, re.sub(r"[\n\r\t ]", " ", value).strip()) File "/Users/my_user/.pyenv/versions/3.10.10/envs/virt_python3/lib/python3.10/site-packages/zeep/xsd/types/builtins.py", line 180, in pythonvalue return isodate.parse_datetime(value) File "/Users/my_user/.pyenv/versions/3.10.10/envs/virt_python3/lib/python3.10/site-packages/isodate/isodatetime.py", line 56, in parse_datetime tmptime = parse_time(timestring) File "/Users/my_user/.pyenv/versions/3.10.10/envs/virt_python3/lib/python3.10/site-packages/isodate/isotime.py", line 134, in parse_time return time(int(groups['hour']), int(groups['minute']), ValueError: second must be in 0..59

We think that the code should be rounding this to the next minute or rounding down millisecond to the best 99999 value. But in the mean-time we have manually updated the isotime.py script locally with the following code:

if Decimal(groups['second']) > 59: second = (Decimal(groups['second']) - 1).quantize(Decimal('.000001')) else: second = Decimal(groups['second']).quantize(Decimal('.000001'))

Let us know if you need any more details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant