Temporal.TimeZone.from('+00:00:00.1').getOffsetStringFor(Temporal.Now.instant())
// Intended: "+00:00:00.1"// Actual, according to current spec text: "+00:00"
Failed to account for the case of 0 decimal digits
d = Temporal.Duration.from({ seconds: 5 });
d.toString({ fractionalSecondDigits: 0 })
// Intended: "PT5S"// Actual, according to current spec text: "PT5.000000000S"
A repeated line in the spec text undid the effect of the first line
april = Temporal.PlainYearMonth.from('2021-04');
october = Temporal.PlainYearMonth.from('2021-10');
october.since(april, { smallestUnit: 'year', roundingMode: 'ceil' }).years
// Intended: 1// Actual, according to current spec text: 0
october.since(april, { smallestUnit: 'year', roundingMode: 'floor' }).years
// Intended: 0// Actual, according to current spec text: 1
If a primitive corresponds to a bag property, is it req'd in object form?
Choice 1: MUST. "Required" should mean it's required everywhere
Choice 2: SHOULD, except unusual cases like:
"1 of N are required" properties
mutually-exclusive properties
primitives that can aggregate multiple properties
Looking for consensus opinion about which choice is best
duration.round('day') // Proposed change
duration.round({ smallestUnit: 'day' }) // Current behavior, equivalent to line above// Current behavior: either smallestUnit or largestUnit is required. Must change?
duration.round({ largestUnit: 'month' })
Current Temporal Stage 3 proposal uses (3) because:
It's a no-op and almost certainly a bug
To defend against prop-name typos like .round({smalestUnit: 'second'})
Is there a compelling reason to change current Stage 3 behavior?
Asking for consensus (again)
// Unusual case #2: primitives that are aggregations (hypothetical API; not Temporal)
f(0b111)
f({ read: true, write: true, execute: true })
---
### Patterns for optional/required params ([#1756](https://github.com/tc39/proposal-temporal/issues/1756))
- Optional params SHOULD be a property bag to support future extension
```js
JSON.stringify({ x }, undefined, 2) // ❌ SHOULD NOT make new APIs with positional, optional params
new Intl.DisplayNames(undefined, { type }) // ✅ MAY stay consistent with existing APIs
```
- Required params SHOULD NOT be property bags
- Exception: "primitive | bag" polymorphic param MAY be required
```js
duration.round() // ❌ throws because it's a no-op
duration.round('day') // ✅ (proposed change to Temporal API)
duration.round({ smallestUnit: 'hour' }) // ✅ same as .round('day')
duration.round({ smallestUnit: 'hour', roundingIncrement: 12 }) // ✅ other optional props
```
- Exception: bags for "data" (not options) MAY be required
```js
plainDate.with() // ❌ throws because it's a no-op
plainDate.with({ day: 1, month: 2 }) // ✅ required param with optional props
```
---
### Alternatives considered and rejected
```js
// ❌ why let users write code that's guaranteed to be wrong?
pdt.round();
// ❌ splitting options bags on required vs. optional seems verbose and hostile.
pdt.round({ smallestUnit: 'day' }, { roundingMode: 'ceil' });
// ❌ less bad than above, but still makes it harder for users to reuse learning
// and code for round() and until()/since() options.
pdt.round('day', { roundingMode: 'ceil' });
// ❌ removing rounding from `until` and `since` to solve options shape corner case seems like overkill.
pdt.until('2020-01-01');
```
---
### DISCUSSION: req'd vs. optional params patterns?
Problem to solve: options objects where properties are required in some APIs or cases but optional in others.
```js
pdt = Temporal.PlainDateTime.from('2021-10-28T10:00');
roundingOpts = { smallestUnit: 'day', roundingMode: 'ceil' };
// `smallestUnit` option is optional for `until` and `since`
notRounded = pdt.since('2021-01-01');
fullDays = pdt.since('2021-01-01', { smallestUnit: 'day' });
partialDays = pdt.since('2021-01-01', roundingOpts);
// `smallestUnit` option is required for `round`
pdt.round(); // throws (to avoid no-op calls)
closestMidnight = pdt.round({ smallestUnit: 'day' });
nextMidnight = pdt.round(roundingOpts);
```