-
Notifications
You must be signed in to change notification settings - Fork 162
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
polyfill: durations accept fractional time values #1179
Conversation
Codecov Report
@@ Coverage Diff @@
## main #1179 +/- ##
==========================================
+ Coverage 93.55% 96.01% +2.46%
==========================================
Files 19 19
Lines 7961 9265 +1304
Branches 1264 1404 +140
==========================================
+ Hits 7448 8896 +1448
+ Misses 506 363 -143
+ Partials 7 6 -1
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, with one question and a few suggestions re: test cases.
'P1Y1M1W1DT0.5H', | ||
'P1Y1M1W1DT1H0,5M', | ||
'P1Y1M1W1DT1H0.5M0.5S' | ||
{ years: 0.5 }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO, all these rounding tests should be done with both positive and negative durations, because a frequent cause of rounding errors in libraries is differences in handling negative vs. positive numbers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good, the main change is that I think we should throw on more than our supported maximum number of decimal places, as per ISO 8601.
fHours, | ||
minutes, | ||
fMinutes, | ||
seconds, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it shouldn't be necessary to pass the seconds, milliseconds, microseconds and nanoseconds into DurationHandleFractions when parsing a string: the result is already handled exactly in the existing code. You can do something like this:
({ minutes, seconds } = ES.DurationHandleFractions(fHours, minutes, fMinutes, 0, 0, 0, 0, 0, 0, 0, 0);
and let the seconds and sub-second units be determined as they already were.
(Although then you do need to ensure that the seconds are not given in the string, if minutes are fractional.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Although then you do need to ensure that the seconds are not given in the string, if minutes are fractional.)
Exactly why I did it this way.
@@ -793,15 +918,15 @@ export const ES = ObjectAssign({}, ES2020, { | |||
if (validUnits.indexOf(unit1) > validUnits.indexOf(unit2)) return unit2; | |||
return unit1; | |||
}, | |||
ToPartialRecord: (bag, fields) => { | |||
ToPartialRecord: (bag, fields, cast = ES.ToInteger) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure the spec language has first-class abstract operations like this, but, maybe consider instead splitting BUILTIN_FIELDS
into BUILTIN_DATETIME_FIELDS
and DURATION_FIELDS
, and using ToNumber
on duration fields?
9c79f9e
to
148f2b0
Compare
I noticed from the CI output that the "order of operations" test262 tests supply non-integer input, those are breaking now instead of truncating it. |
As I explained in #938 (comment) , I think this PR should be dropped. |
This PR still implements support for ISO strings such as |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should block this PR on any of the remaining comments, since they are minor improvements, so I think punting them to a followup is fine.
@@ -949,10 +987,10 @@ <h1>ISO 8601 grammar</h1> | |||
Digits TimeFraction? SecondsDesignator | |||
|
|||
DurationMinutes : | |||
Digits MinutesDesignator DurationSeconds? | |||
Digits TimeFraction? MinutesDesignator DurationSeconds? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the grammar should show that the fraction is incompatible with the seconds part:
DurationMinutes :
Digits MinutesDesignator DurationSeconds?
Digits TimeFraction MinutesDesignator
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What we're doing right now is accept a duration with all the fractions, set the units to zero appropriately and handle them that way. We could change the spec text and instead of throwing at a later time, removing all those checks etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not 100% sure, but I think PT0.5H30M
is actually illegal according to ISO 8601. In the polyfill it doesn't matter whether we throw because it's not accepted by the regex or we throw right after, but I think the spec grammar should match what's a legal string as much as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. Only the smallest unit is permitted to be fractional in ISO 8601.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The string still throws, it just throws after the parsing stage (in DurationHandleFractions
). I thought it was okay as long as we threw on the wrong format.
@@ -1198,42 +1236,51 @@ <h1>ParseTemporalDurationString ( _isoString_ )</h1> | |||
1. Assert: Type(_isoString_) is String. | |||
1. If _isoString_ does not satisfy the syntax of a |TemporalDurationString| (see <emu-xref href="#sec-temporal-iso8601grammar"></emu-xref>), then | |||
1. Throw a *RangeError* exception. | |||
1. Let _sign_, _years_, _months_, _weeks_, _days_, _hours_, _minutes_, _seconds_, and _fraction_ be the parts of _isoString_ produced respectively by the |Sign|, |DurationYears|, |DurationMonths|, |DurationWeeks|, |DurationDays|, |DurationHours|, |DurationMinutes|, |DurationSeconds|, and |TimeFractionalPart| productions, or *undefined* if not present. | |||
1. Let _sign_, _years_, _months_, _weeks_, _days_, _hours_, _fHours_, _minutes_, _fMinutes_, _seconds_, and _fSeconds_ be the parts of _isoString_ produced respectively by the |Sign|, |DurationYears|, |DurationMonths|, |DurationWeeks|, |DurationDays|, |DurationHours|, |DurationHoursFraction|, |DurationMinutes|, |DurationMinutesFraction|, |DurationSeconds|, and |DurationSecondsFraction| productions, or *undefined* if not present. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DurationHoursFraction, DurationMinutesFraction, and DurationSecondsFraction need to be defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we use |TimeFractionalPart|
three times over?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think you can just define them like DurationHoursFraction : TimeFractionalPart
etc.
- Fix order-of-operations tests (which used 1.7 as a value for durations and relied upon it being truncated to 1, which we probably don't want regardless of the state of this) - Remove Duration.from subclass-invalid-arg test, which is no longer valid; the subclass constructor is never called with a non-float argument - Fix ecmarkup linter errors
OK, merging this now, we should solve the remaining comments in a follow up soon, ideally when the discussion in #938 is resolved. |
Fixes: #938
/cc @justingrant @ptomato