-
Notifications
You must be signed in to change notification settings - Fork 159
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
Arithmetic with out-of-scope duration fields #324
Comments
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I agree it should be valid to have a Duration object with too-high values. However I just realized that means we need to re-think which Duration fields we allow in the various arithmetic methods. For example we throw a RangeError if you do this: const wallClockNow = Temporal.now.time()
wallClockNow.plus({days: 2}) // throws if one of days, months, or years ≠ 0 but not this: wallClockNow.plus({hours: 48}) // doesn't throw This also goes for MonthDay since you can add or subtract months ≥ 12 or days ≥ 365. |
I'm not sure what the rationale would be that would lead the first example to throw. Anything that lets me "plus" anything should let me plus everything, no? |
I misread the post too. What @ptomato is saying is that since In situations like this, we could:
Note: @pipobscure has pointed out before that since the durations can be data-driven, like reading a string from a database or from user input, it would be undesirable to have .plus/.minus throw RangeError dependent on the fields in the duration. @younies Thoughts on this? |
Other cases of particular interest include |
I'd propose option 2 for units that are too large for the type (e.g. adding years to Time), because they have no effect on the result. However, I'd propose option 3 for units that are too small for the type (e.g. adding hours to Date) because of what @gibson042 mentioned above. |
If we do option 3 only in one direction, what happens when you do
The number of days depends on the month of course. I guess the semantic could be: expand the type to DateTime (both Date and YearMonth) at midnight on the first of the month; add the fields; disambiguate according to the input option; and then convert back to the input type (which truncates). Does that work? |
That would work IMO. On the other hand maybe the answer is to treat YearMonth differently than Date since |
If you want YearMonth arithmetic to be predictable, then don't give it days. This is an edge case where we're trying to figure out the best behavior. |
For the new question at hand here, I think it's fine to ignore fields that are too large, but methods should throw when the input includes nonzero fields that are too small for their type (because there's no general way to support them). let date = Temporal.Date.from("2020-02-16");
assert.strictEquals(date.plus({hours: 0}).toString(), "2020-02-16");
Array(60).fill().map((_, i) => i + 1).forEach(hours =>
assert.throws(() => date.plus({hours}));
);
let yearMonth = Temporal.YearMonth.from("2020-02");
assert.strictEquals(yearMonth.plus({days: 0}).toString(), "2020-02");
Array(60).fill().map((_, i) => i + 1).forEach(days =>
assert.throws(() => yearMonth.plus({days}));
); If you want to do arithmetic with smaller units, then first map the receiver to a type that understands them (e.g., |
I'm slightly confused by your comment, because 3 days ago, you said:
Now you are suggesting that we throw when the fields are too small. |
Ignoring the non-overlapping fields will definitely surprise authors, so they should not be ignored. And because too-small fields cannot be processed in the general case (e.g. adding 36 hours to a Temporal.Date), the proper alternative to ignoring them is rejection. Too-large fields that can't affect the calculation (e.g., |
Consensus is to go with Option 3 from #324 (comment) |
So what happens for |
The duration would be balanced into
The answer would be the same for all hours between 24 and 47 inclusive.
Now you're adding 2 days. |
I object to that treatment, but am not prepared to fight consensus at this time. |
* Arithmetic with out-of-scope units for Date, Time, YearMonth Out-of-scope units are ignored if they are higher than the type's units and wouldn't have any effect (e.g. adding years to a Time). Out-of-scope units are balanced up to the type's lowest unit if they are lower than the type's units, and any remaining fractions of the type's lowest unit are ignored (e.g. adding 36 hours to a Date adds 1 day.) In the case of YearMonth, days are balanced into months based on the first day of the month. Closes: #324 Co-Authored-By: Ms2ger <[email protected]> Co-authored-by: Ms2ger <[email protected]>
See #388 for the original discussion regarding Temporal.Duration and disambiguation = "balance"
The text was updated successfully, but these errors were encountered: