Skip to content

Fix parsing of fractional durations #13832

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

Merged

Conversation

urmastalimaa
Copy link
Contributor

@urmastalimaa urmastalimaa commented Sep 17, 2024

The parsing of fractional durations checked for non-negativity by testing second > 0, which reports false for not only negative integers but also for 0.

The JavaScript libraries that I tested disagree whether "-PT-0,6S" represents a positive or negative duration, "moment" and "tinyduration" reported positive, "luxon" (the successor to moment) reported negative. My reading of the specification gives me no reason to doubt that a double negative should result in anything but a positive total result.

It is worth mentioning that as the scale units are represented as integers, there is no clean way to implement fractional parsing of non-second units. Currently, fractional non-second durations simply fail to parse. Wikipedia gives "0.5Y" as an example.

@urmastalimaa urmastalimaa force-pushed the fix_fractional_duration_parsing branch 2 times, most recently from 20f9478 to dbdd9be Compare September 17, 2024 14:13
@josevalim
Copy link
Member

cc @tfiedlerdejanze you happy with this change?

@urmastalimaa
Copy link
Contributor Author

urmastalimaa commented Sep 17, 2024

I'll clarify that I didn't change the possibility and interpretation of double negatives.
But as I did change the construction of negative fractionals, I added a test and kept existing behaviour for "-PT-0,NS".

@tfiedlerdejanze
Copy link
Contributor

tfiedlerdejanze commented Sep 17, 2024

FWIW i'd also find it counter-intuitive for "-PT-0,6S" to result in a negative duration.

As the change doesn't affect the actual behaviour i am fine with it however, while it makes sense to me in theory i fail to see the practical benefit of it. @urmastalimaa does this actually fix a case that's currently wrongly parsed?

Totally missed you added this with the first test, sorry. I am fine with the fix!

Currently, fractional non-second durations simply fail to parse. Wikipedia gives "0.5Y" as an example.

this is correct, it was intended for us to support fractional units for the smallest time unit only for now.

@urmastalimaa urmastalimaa force-pushed the fix_fractional_duration_parsing branch 2 times, most recently from 51b9123 to 762c992 Compare September 18, 2024 06:25
Existing behaviour is to accept fractions only in the second components
Extend tests for existing fractional durations parsing behaviour.

Parsing "PT0,6S" should result in a positive microsecond, which will be
fixed in the next commit.

The parser currently accepts both a negative prefix "-PT" and a negative
value in the components "-0,6S". Combining both into "-PT-0,6S" is also
accepted by the parser, resulting in an overall positive duration.
Although the practical value of double negative durations is dubious,
the accepting nature of the parser is tested.

The JavaScript libraries that I tested disagree whether "-PT-0,6S"
represents a positive or negative duration, "moment" and "tinyduration"
reported positive, "luxon" (the successor to moment) reported negative.
If the parser accepts double negatives at all, resulting in anything but
a positive duration would be unintuitive.
The parsing of fractional durations checked for non-negativity by
testing second > 0, which reports false for not only negative integers
but also for 0.

Note that changing `if second > 0` to `if second >= 0` would fix
behaviour for "PT0,6S", but would break "PT-0,6S".
@urmastalimaa urmastalimaa force-pushed the fix_fractional_duration_parsing branch from 762c992 to 5678a33 Compare September 18, 2024 06:28
@urmastalimaa
Copy link
Contributor Author

urmastalimaa commented Sep 18, 2024

Thanks for the context.

Me getting on tangents without stressing what is being fixed caused a bit of confusion, my apologies.
I split the change into three commits to be clearer

  1. Added tests for existing behaviour about rejecting fractions for non-second components
  2. Added tests for existing behaviour about fractional durations with 0 in the integer component, including a case for the existing bug
  3. Fix for parsing fractionals with 0 in the integer component

@josevalim josevalim merged commit 7a634a2 into elixir-lang:main Sep 18, 2024
9 checks passed
@josevalim
Copy link
Member

💚 💙 💜 💛 ❤️

josevalim pushed a commit that referenced this pull request Sep 18, 2024
The parsing of fractional durations checked for non-negativity by
testing second > 0, which reports false for not only negative integers
but also for 0.

Note that changing `if second > 0` to `if second >= 0` would fix
behaviour for "PT0,6S", but would break "PT-0,6S".
@urmastalimaa urmastalimaa deleted the fix_fractional_duration_parsing branch September 20, 2024 05:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants