mirror of https://github.com/tc39/test262.git
Temporal: Limit duration years, months, and weeks to <2³² each
This commit is contained in:
parent
01ec9938bb
commit
99d5bc8c1b
|
@ -11,6 +11,12 @@ features: [Temporal]
|
|||
const instance = new Temporal.Calendar("iso8601");
|
||||
|
||||
const maxCases = [
|
||||
["P273790Y8M12DT23H59M59.999999999S", "string with max years"],
|
||||
[{ years: 273790, months: 8, days: 12, nanoseconds: 86399999999999 }, "property bag with max years"],
|
||||
["P3285488M12DT23H59M59.999999999S", "string with max months"],
|
||||
[{ months: 3285488, days: 12, nanoseconds: 86399999999999 }, "property bag with max months"],
|
||||
["P14285714W2DT23H59M59.999999999S", "string with max weeks"],
|
||||
[{ weeks: 14285714, days: 2, nanoseconds: 86399999999999 }, "property bag with max weeks"],
|
||||
["P100000000DT23H59M59.999999999S", "string with max days"],
|
||||
[{ days: 100000000, nanoseconds: 86399999999999 }, "property bag with max days"],
|
||||
["PT2400000023H59M59.999999999S", "string with max hours"],
|
||||
|
@ -27,6 +33,12 @@ for (const [arg, descr] of maxCases) {
|
|||
}
|
||||
|
||||
const minCases = [
|
||||
["-P273790Y8M12DT23H59M59.999999999S", "string with min years"],
|
||||
[{ years: -273790, months: -8, days: -12, nanoseconds: -86399999999999 }, "property bag with min years"],
|
||||
["-P3285488M12DT23H59M59.999999999S", "string with min months"],
|
||||
[{ months: -3285488, days: -12, nanoseconds: -86399999999999 }, "property bag with min months"],
|
||||
["-P14285714W3DT23H59M59.999999999S", "string with min weeks"],
|
||||
[{ weeks: -14285714, days: -3, nanoseconds: -86399999999999 }, "property bag with min weeks"],
|
||||
["-P100000001DT23H59M59.999999999S", "string with min days"],
|
||||
[{ days: -100000001, nanoseconds: -86399999999999 }, "property bag with min days"],
|
||||
["-PT2400000047H59M59.999999999S", "string with min hours"],
|
||||
|
|
|
@ -10,6 +10,20 @@ features: [Temporal]
|
|||
const instance = new Temporal.Calendar("iso8601");
|
||||
|
||||
const cases = [
|
||||
// 2^32 = 4294967296
|
||||
["P4294967296Y", "string with years > max"],
|
||||
[{ years: 4294967296 }, "property bag with years > max"],
|
||||
["-P4294967296Y", "string with years < min"],
|
||||
[{ years: -4294967296 }, "property bag with years < min"],
|
||||
["P4294967296M", "string with months > max"],
|
||||
[{ months: 4294967296 }, "property bag with months > max"],
|
||||
["-P4294967296M", "string with months < min"],
|
||||
[{ months: -4294967296 }, "property bag with months < min"],
|
||||
["P4294967296W", "string with weeks > max"],
|
||||
[{ weeks: 4294967296 }, "property bag with weeks > max"],
|
||||
["-P4294967296W", "string with weeks < min"],
|
||||
[{ weeks: -4294967296 }, "property bag with weeks < min"],
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
/*---
|
||||
esid: sec-temporal.calendar.prototype.dateadd
|
||||
description: >
|
||||
Call BalanceISOYearMonth with Number.MAX_VALUE and -Number.MAX_VALUE for years/months.
|
||||
Call BalanceISOYearMonth with 2³² - 1 and -(2³² - 1) for years/months.
|
||||
info: |
|
||||
Temporal.Calendar.prototype.dateAdd ( date, duration [ , options ] )
|
||||
|
||||
|
@ -26,8 +26,10 @@ features: [Temporal]
|
|||
var cal = new Temporal.Calendar("iso8601");
|
||||
var date = new Temporal.PlainDate(1970, 1, 1);
|
||||
|
||||
var maxValue = new Temporal.Duration(Number.MAX_VALUE, Number.MAX_VALUE);
|
||||
var minValue = new Temporal.Duration(-Number.MAX_VALUE, -Number.MAX_VALUE);
|
||||
const max = 4294967295; // 2³² - 1
|
||||
|
||||
var maxValue = new Temporal.Duration(max, max);
|
||||
var minValue = new Temporal.Duration(-max, -max);
|
||||
|
||||
assert.throws(RangeError, () => cal.dateAdd(date, maxValue), "years/months is +Number.MAX_VALUE");
|
||||
assert.throws(RangeError, () => cal.dateAdd(date, minValue), "years/months is -Number.MAX_VALUE");
|
||||
|
|
|
@ -8,6 +8,20 @@ features: [Temporal]
|
|||
---*/
|
||||
|
||||
const cases = [
|
||||
// 2^32 = 4294967296
|
||||
["P4294967296Y", "string with years > max"],
|
||||
[{ years: 4294967296 }, "property bag with years > max"],
|
||||
["-P4294967296Y", "string with years < min"],
|
||||
[{ years: -4294967296 }, "property bag with years < min"],
|
||||
["P4294967296M", "string with months > max"],
|
||||
[{ months: 4294967296 }, "property bag with months > max"],
|
||||
["-P4294967296M", "string with months < min"],
|
||||
[{ months: -4294967296 }, "property bag with months < min"],
|
||||
["P4294967296W", "string with weeks > max"],
|
||||
[{ weeks: 4294967296 }, "property bag with weeks > max"],
|
||||
["-P4294967296W", "string with weeks < min"],
|
||||
[{ weeks: -4294967296 }, "property bag with weeks < min"],
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
|
|
|
@ -8,6 +8,12 @@ features: [Temporal]
|
|||
---*/
|
||||
|
||||
const maxCases = [
|
||||
["P4294967295Y104249991374DT7H36M31.999999999S", "string with max years"],
|
||||
[{ years: 4294967295, days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max years"],
|
||||
["P4294967295M104249991374DT7H36M31.999999999S", "string with max weeks"],
|
||||
[{ months: 4294967295, days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max months"],
|
||||
["P4294967295W104249991374DT7H36M31.999999999S", "string with max weeks"],
|
||||
[{ weeks: 4294967295, days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max weeks"],
|
||||
["P104249991374DT7H36M31.999999999S", "string with max days"],
|
||||
[{ days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max days"],
|
||||
["PT2501999792983H36M31.999999999S", "string with max hours"],
|
||||
|
@ -20,10 +26,16 @@ const maxCases = [
|
|||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = Temporal.Duration.from(arg);
|
||||
assert.sameValue(result.total("seconds"), 9007199254740991.999999999, `operation succeeds with ${descr}`);
|
||||
assert.sameValue(result.with({ years: 0, months: 0, weeks: 0 }).total("seconds"), 9007199254740991.999999999, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
["-P4294967295Y104249991374DT7H36M31.999999999S", "string with min years"],
|
||||
[{ years: -4294967295, days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min years"],
|
||||
["-P4294967295M104249991374DT7H36M31.999999999S", "string with min months"],
|
||||
[{ months: -4294967295, days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min months"],
|
||||
["-P4294967295W104249991374DT7H36M31.999999999S", "string with min weeks"],
|
||||
[{ weeks: -4294967295, days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min weeks"],
|
||||
["-P104249991374DT7H36M31.999999999S", "string with min days"],
|
||||
[{ days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min days"],
|
||||
["-PT2501999792983H36M31.999999999S", "string with min hours"],
|
||||
|
@ -36,5 +48,5 @@ const minCases = [
|
|||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = Temporal.Duration.from(arg);
|
||||
assert.sameValue(result.total("seconds"), -9007199254740991.999999999, `operation succeeds with ${descr}`);
|
||||
assert.sameValue(result.with({ years: 0, months: 0, weeks: 0 }).total("seconds"), -9007199254740991.999999999, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
/*---
|
||||
esid: sec-temporal.duration
|
||||
description: Maximum values of arguments to the Duration constructor
|
||||
includes: [temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
|
@ -21,3 +22,9 @@ const cases = [
|
|||
for (const [d, descr, expected] of cases) {
|
||||
assert.sameValue(d.total("seconds"), expected, descr);
|
||||
}
|
||||
|
||||
// 2^32 - 1 = 4294967295
|
||||
const max = new Temporal.Duration(4294967295, 4294967295, 4294967295, 104249991374, 7, 36, 31, 999, 999, 999);
|
||||
TemporalHelpers.assertDuration(max, 4294967295, 4294967295, 4294967295, 104249991374, 7, 36, 31, 999, 999, 999);
|
||||
const min = new Temporal.Duration(-4294967295, -4294967295, -4294967295, -104249991374, -7, -36, -31, -999, -999, -999);
|
||||
TemporalHelpers.assertDuration(min, -4294967295, -4294967295, -4294967295, -104249991374, -7, -36, -31, -999, -999, -999);
|
||||
|
|
|
@ -7,6 +7,14 @@ description: Various arguments to the Duration constructor that are out of range
|
|||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// 2^32 = 4294967296
|
||||
assert.throws(RangeError, () => new Temporal.Duration(4294967296), "years > max");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(-4294967296), "years < min");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 4294967296), "months > max");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, -4294967296), "months < min");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 4294967296), "days > max");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, -4294967296), "days < min");
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 104249991375), "days > max");
|
||||
assert.throws(RangeError, () => new Temporal.Duration(0, 0, 0, 104249991374, 24), "hours balance into days > max");
|
||||
|
|
|
@ -10,6 +10,20 @@ features: [Temporal]
|
|||
const instance = new Temporal.Duration();
|
||||
|
||||
const cases = [
|
||||
// 2^32 = 4294967296
|
||||
["P4294967296Y", "string with years > max"],
|
||||
[{ years: 4294967296 }, "property bag with years > max"],
|
||||
["-P4294967296Y", "string with years < min"],
|
||||
[{ years: -4294967296 }, "property bag with years < min"],
|
||||
["P4294967296M", "string with months > max"],
|
||||
[{ months: 4294967296 }, "property bag with months > max"],
|
||||
["-P4294967296M", "string with months < min"],
|
||||
[{ months: -4294967296 }, "property bag with months < min"],
|
||||
["P4294967296W", "string with weeks > max"],
|
||||
[{ weeks: 4294967296 }, "property bag with weeks > max"],
|
||||
["-P4294967296W", "string with weeks < min"],
|
||||
[{ weeks: -4294967296 }, "property bag with weeks < min"],
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
|
|
|
@ -22,7 +22,7 @@ const maxCases = [
|
|||
|
||||
for (const [arg, descr] of maxCases) {
|
||||
const result = instance.subtract(arg);
|
||||
assert.sameValue(result.total("seconds"), -9007199254740991.999999999, `operation succeeds with ${descr}`);
|
||||
assert.sameValue(result.with({ years: 0, months: 0, weeks: 0 }).total("seconds"), -9007199254740991.999999999, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
||||
const minCases = [
|
||||
|
@ -38,5 +38,5 @@ const minCases = [
|
|||
|
||||
for (const [arg, descr] of minCases) {
|
||||
const result = instance.subtract(arg);
|
||||
assert.sameValue(result.total("seconds"), 9007199254740991.999999999, `operation succeeds with ${descr}`);
|
||||
assert.sameValue(result.with({ years: 0, months: 0, weeks: 0 }).total("seconds"), 9007199254740991.999999999, `operation succeeds with ${descr}`);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,20 @@ features: [Temporal]
|
|||
const instance = new Temporal.Duration();
|
||||
|
||||
const cases = [
|
||||
// 2^32 = 4294967296
|
||||
["P4294967296Y", "string with years > max"],
|
||||
[{ years: 4294967296 }, "property bag with years > max"],
|
||||
["-P4294967296Y", "string with years < min"],
|
||||
[{ years: -4294967296 }, "property bag with years < min"],
|
||||
["P4294967296M", "string with months > max"],
|
||||
[{ months: 4294967296 }, "property bag with months > max"],
|
||||
["-P4294967296M", "string with months < min"],
|
||||
[{ months: -4294967296 }, "property bag with months < min"],
|
||||
["P4294967296W", "string with weeks > max"],
|
||||
[{ weeks: 4294967296 }, "property bag with weeks > max"],
|
||||
["-P4294967296W", "string with weeks < min"],
|
||||
[{ weeks: -4294967296 }, "property bag with weeks < min"],
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal-temporaldurationtostring
|
||||
description: >
|
||||
Duration components are formatted as precise decimal numbers.
|
||||
info: |
|
||||
TemporalDurationToString ( years, months, weeks, days, hours, minutes, seconds, milliseconds,
|
||||
microseconds, nanoseconds, precision )
|
||||
...
|
||||
9. If years is not 0, then
|
||||
a. Set datePart to the string concatenation of abs(years) formatted as a decimal number and
|
||||
the code unit 0x0059 (LATIN CAPITAL LETTER Y).
|
||||
10. If months is not 0, then
|
||||
a. Set datePart to the string concatenation of datePart, abs(months) formatted as a decimal
|
||||
number, and the code unit 0x004D (LATIN CAPITAL LETTER M).
|
||||
If weeks is not 0, then
|
||||
a. Set datePart to the string concatenation of datePart, abs(weeks) formatted as a decimal
|
||||
number, and the code unit 0x0057 (LATIN CAPITAL LETTER W).
|
||||
...
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
{
|
||||
let d = Temporal.Duration.from({weeks: 10000000000000004000});
|
||||
|
||||
// Number(10000000000000004000).toString() is "10000000000000004000".
|
||||
assert.sameValue(d.toString(), "P10000000000000004096W");
|
||||
}
|
||||
|
||||
{
|
||||
let d = Temporal.Duration.from({months: 9e59});
|
||||
|
||||
// Number(9e+59).toString() is "9e+59".
|
||||
assert.sameValue(d.toString(), "P899999999999999918767229449717619953810131273674690656206848M");
|
||||
}
|
||||
|
||||
{
|
||||
let d = Temporal.Duration.from({years: Number.MAX_VALUE});
|
||||
|
||||
// Number.MAX_VALUE.toString() is "1.7976931348623157e+308".
|
||||
assert.sameValue(d.toString(), "P179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368Y");
|
||||
}
|
118
test/built-ins/Temporal/Duration/prototype/total/precision-exact-mathematical-values-3.js
vendored
Normal file
118
test/built-ins/Temporal/Duration/prototype/total/precision-exact-mathematical-values-3.js
vendored
Normal file
|
@ -0,0 +1,118 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.total
|
||||
description: >
|
||||
RoundDuration computes in such a way as to avoid precision loss when the
|
||||
computed day, week, month, and year lengths are very large numbers.
|
||||
info: |
|
||||
RoundDuration:
|
||||
...
|
||||
7. If _unit_ is one of *"year"*, *"month"*, *"week"*, or *"day"*, then
|
||||
a. If _zonedRelativeTo_ is not *undefined*, then
|
||||
...
|
||||
iii. Let _fractionalDays_ be _days_ + _result_.[[Days]] + DivideNormalizedTimeDuration(_result_.[[Remainder]], _result_.[[DayLength]]).
|
||||
...
|
||||
10. If _unit_ is *"year"*, then
|
||||
...
|
||||
z. Let _fractionalYears_ be _years_ + _fractionalDays_ / abs(_oneYearDays_).
|
||||
...
|
||||
11. If _unit_ is *"month"*, then
|
||||
...
|
||||
z. Let _fractionalMonths_ be _months_ + _fractionalDays_ / abs(_oneMonthDays_).
|
||||
...
|
||||
12. If _unit_ is *"week"*, then
|
||||
...
|
||||
s. Let _fractionalWeeks_ be _weeks_ + _fractionalDays_ / abs(_oneWeekDays_).
|
||||
includes: [compareArray.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Return the next Number value in direction to +Infinity.
|
||||
function nextUp(num) {
|
||||
if (!Number.isFinite(num)) {
|
||||
return num;
|
||||
}
|
||||
if (num === 0) {
|
||||
return Number.MIN_VALUE;
|
||||
}
|
||||
|
||||
var f64 = new Float64Array([num]);
|
||||
var u64 = new BigUint64Array(f64.buffer);
|
||||
u64[0] += (num < 0 ? -1n : 1n);
|
||||
return f64[0];
|
||||
}
|
||||
|
||||
// Return the next Number value in direction to -Infinity.
|
||||
function nextDown(num) {
|
||||
if (!Number.isFinite(num)) {
|
||||
return num;
|
||||
}
|
||||
if (num === 0) {
|
||||
return -Number.MIN_VALUE;
|
||||
}
|
||||
|
||||
var f64 = new Float64Array([num]);
|
||||
var u64 = new BigUint64Array(f64.buffer);
|
||||
u64[0] += (num < 0 ? 1n : -1n);
|
||||
return f64[0];
|
||||
}
|
||||
|
||||
// Return bit pattern representation of Number as a Uint8Array of bytes.
|
||||
function f64Repr(f) {
|
||||
const buf = new ArrayBuffer(8);
|
||||
new DataView(buf).setFloat64(0, f);
|
||||
return new Uint8Array(buf);
|
||||
}
|
||||
|
||||
// ============
|
||||
|
||||
const tz = new (class extends Temporal.TimeZone {
|
||||
getPossibleInstantsFor() {
|
||||
// Called in NormalizedTimeDurationToDays 21.a from RoundDuration 7.b.
|
||||
// Sets _result_.[[DayLength]] to 2⁵³ - 1 ns, its largest possible value
|
||||
return [new Temporal.Instant(-86400_0000_0000_000_000_000n + 2n ** 53n - 1n)];
|
||||
}
|
||||
})("UTC");
|
||||
|
||||
const cal = new (class extends Temporal.Calendar {
|
||||
dateAdd() {
|
||||
// Called in MoveRelativeDate from RoundDuration 10.x, 11.x, or 12.q.
|
||||
// Sets _oneYearDays_, _oneMonthDays_, or _oneWeekDays_ respectively to
|
||||
// 200_000_000, its largest possible value.
|
||||
return new Temporal.PlainDate(275760, 9, 13);
|
||||
}
|
||||
})("iso8601");
|
||||
|
||||
const relativeTo = new Temporal.ZonedDateTime(-86400_0000_0000_000_000_000n, tz, cal);
|
||||
const d = new Temporal.Duration(0, 0, 0, 0, 0, 0, 0, 0, 0, /* nanoseconds = */ 1);
|
||||
|
||||
/*
|
||||
* RoundDuration step 7:
|
||||
* ii. result = { [[Days]] = 0, [[Remainder]] = normalized time duration of 1 ns,
|
||||
* [[DayLength]] = Number.MAX_SAFE_INTEGER }
|
||||
* iii. fractionalDays = 0 + 0 + 1 / Number.MAX_SAFE_INTEGER
|
||||
* step 10:
|
||||
* y. oneYearDays = 200_000_000
|
||||
* z. fractionalYears = 0 + (1 / Number.MAX_SAFE_INTEGER) / 200_000_000
|
||||
*/
|
||||
// Calculated with Python's Decimal module to 50 decimal places
|
||||
const expected = 5.55111512312578_3318415740544369642963189519987393e-25;
|
||||
|
||||
// Check that we are not accidentally losing precision in our expected value:
|
||||
|
||||
assert.sameValue(expected, 5.55111512312578_373662e-25, "the float representation of the result is 5.55111512312578373662e-25");
|
||||
assert.compareArray(
|
||||
f64Repr(expected),
|
||||
[0x3a, 0xe5, 0x79, 0x8e, 0xe2, 0x30, 0x8c, 0x3b],
|
||||
"the bit representation of the result is 0x3ae5798ee2308c3b"
|
||||
);
|
||||
// The next Number in direction -Infinity is less precise.
|
||||
assert.sameValue(nextDown(expected), 5.55111512312578_281826e-25, "the next Number in direction -Infinity is less precise");
|
||||
// The next Number in direction +Infinity is less precise.
|
||||
assert.sameValue(nextUp(expected), 5.55111512312578_465497e-25, "the next Number in direction +Infinity is less precise");
|
||||
|
||||
assert.sameValue(d.total({ unit: "years", relativeTo }), expected, "Correct division by large number in years total");
|
||||
assert.sameValue(d.total({ unit: "months", relativeTo }), expected, "Correct division by large number in months total");
|
||||
assert.sameValue(d.total({ unit: "weeks", relativeTo }), expected, "Correct division by large number in weeks total");
|
152
test/built-ins/Temporal/Duration/prototype/total/precision-exact-mathematical-values-4.js
vendored
Normal file
152
test/built-ins/Temporal/Duration/prototype/total/precision-exact-mathematical-values-4.js
vendored
Normal file
|
@ -0,0 +1,152 @@
|
|||
// Copyright (C) 2023 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.total
|
||||
description: >
|
||||
RoundDuration computes in such a way as to avoid precision loss when the
|
||||
computed day, week, month, and year lengths are very large numbers.
|
||||
info: |
|
||||
RoundDuration:
|
||||
...
|
||||
7. If _unit_ is one of *"year"*, *"month"*, *"week"*, or *"day"*, then
|
||||
a. If _zonedRelativeTo_ is not *undefined*, then
|
||||
...
|
||||
iii. Let _fractionalDays_ be _days_ + _result_.[[Days]] + DivideNormalizedTimeDuration(_result_.[[Remainder]], _result_.[[DayLength]]).
|
||||
...
|
||||
10. If _unit_ is *"year"*, then
|
||||
...
|
||||
z. Let _fractionalYears_ be _years_ + _fractionalDays_ / abs(_oneYearDays_).
|
||||
...
|
||||
11. If _unit_ is *"month"*, then
|
||||
...
|
||||
z. Let _fractionalMonths_ be _months_ + _fractionalDays_ / abs(_oneMonthDays_).
|
||||
...
|
||||
12. If _unit_ is *"week"*, then
|
||||
...
|
||||
s. Let _fractionalWeeks_ be _weeks_ + _fractionalDays_ / abs(_oneWeekDays_).
|
||||
includes: [compareArray.js, temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Return the next Number value in direction to +Infinity.
|
||||
function nextUp(num) {
|
||||
if (!Number.isFinite(num)) {
|
||||
return num;
|
||||
}
|
||||
if (num === 0) {
|
||||
return Number.MIN_VALUE;
|
||||
}
|
||||
|
||||
var f64 = new Float64Array([num]);
|
||||
var u64 = new BigUint64Array(f64.buffer);
|
||||
u64[0] += (num < 0 ? -1n : 1n);
|
||||
return f64[0];
|
||||
}
|
||||
|
||||
// Return the next Number value in direction to -Infinity.
|
||||
function nextDown(num) {
|
||||
if (!Number.isFinite(num)) {
|
||||
return num;
|
||||
}
|
||||
if (num === 0) {
|
||||
return -Number.MIN_VALUE;
|
||||
}
|
||||
|
||||
var f64 = new Float64Array([num]);
|
||||
var u64 = new BigUint64Array(f64.buffer);
|
||||
u64[0] += (num < 0 ? 1n : -1n);
|
||||
return f64[0];
|
||||
}
|
||||
|
||||
// Return bit pattern representation of Number as a Uint8Array of bytes.
|
||||
function f64Repr(f) {
|
||||
const buf = new ArrayBuffer(8);
|
||||
new DataView(buf).setFloat64(0, f);
|
||||
return new Uint8Array(buf);
|
||||
}
|
||||
|
||||
// ============
|
||||
// Set up contrived custom time zone and calendar to give dayLengthNs,
|
||||
// oneYearDays, oneMonthDays, and oneWeekDays their largest possible values
|
||||
|
||||
function createTimeZone() {
|
||||
const tz = new Temporal.TimeZone("UTC");
|
||||
TemporalHelpers.substituteMethod(tz, "getPossibleInstantsFor", [
|
||||
TemporalHelpers.SUBSTITUTE_SKIP, // Duration.total step 19.a MoveRelativeZonedDateTime → AddZonedDateTime
|
||||
TemporalHelpers.SUBSTITUTE_SKIP, // Duration.total step 19.e.ii AddDaysToZonedDateTime
|
||||
TemporalHelpers.SUBSTITUTE_SKIP, // Duration.total step 19.i.ii NormalizedTimeDurationToDays step 16
|
||||
TemporalHelpers.SUBSTITUTE_SKIP, // Duration.total step 19.i.ii NormalizedTimeDurationToDays step 19
|
||||
[new Temporal.Instant(-86400_0000_0000_000_000_000n)], // RoundDuration step 7.a.i MoveRelativeZonedDateTime → AddZonedDateTime
|
||||
[new Temporal.Instant(-86400_0000_0000_000_000_000n + 2n ** 53n - 1n)], // RoundDuration step 7.a.ii NormalizedTimeDurationToDays step 19
|
||||
// sets dayLengthNs to Number.MAX_SAFE_INTEGER
|
||||
]);
|
||||
return tz;
|
||||
}
|
||||
|
||||
function createCalendar() {
|
||||
const cal = new Temporal.Calendar("iso8601");
|
||||
TemporalHelpers.substituteMethod(cal, "dateAdd", [
|
||||
TemporalHelpers.SUBSTITUTE_SKIP, // Duration.total step 19.a MoveRelativeZonedDateTime → AddZonedDateTime
|
||||
TemporalHelpers.SUBSTITUTE_SKIP, // RoundDuration step 7.a.i MoveRelativeZonedDateTime → AddZonedDateTime
|
||||
new Temporal.PlainDate(-271821, 4, 20), // RoundDuration step 10.d/11.d AddDate
|
||||
new Temporal.PlainDate(-271821, 4, 20), // RoundDuration step 10.f/11.f AddDate
|
||||
new Temporal.PlainDate(275760, 9, 13), // RoundDuration step 10.r/11.r MoveRelativeDate
|
||||
// sets one{Year,Month,Week}Days to 200_000_000
|
||||
]);
|
||||
return cal;
|
||||
}
|
||||
|
||||
// ============
|
||||
|
||||
// We will calculate the total years/months/weeks of durations with:
|
||||
// 1 year/month/week, 1 day, 0.199000001 s
|
||||
|
||||
// RoundDuration step 7:
|
||||
// ii. result = { [[Days]] = 1, [[Remainder]] = normalized time duration of 199_000_001 ns,
|
||||
// [[DayLength]] = Number.MAX_SAFE_INTEGER }
|
||||
// iii. fractionalDays = 1 + 0 + 199_000_001 / Number.MAX_SAFE_INTEGER
|
||||
// step 10: (similar for steps 11 and 12 in the case of months/weeks)
|
||||
// y. oneYearDays = 200_000_000
|
||||
// z. fractionalYears = 1 + (1 + 199_000_001 / Number.MAX_SAFE_INTEGER) / 200_000_000
|
||||
//
|
||||
// Note: if calculated as 1 + 1/200_000_000 + 199_000_001 / Number.MAX_SAFE_INTEGER / 200_000_000
|
||||
// this will lose precision and give the result 1.000000005.
|
||||
|
||||
// Calculated with Python's Decimal module to 50 decimal places
|
||||
const expected = 1.000000005000000_1104671915053146003490515686745299;
|
||||
|
||||
// Check that we are not accidentally losing precision in our expected value:
|
||||
|
||||
assert.sameValue(expected, 1.000000005000000_2, "the float representation of the result is 1.0000000050000002");
|
||||
assert.compareArray(
|
||||
f64Repr(expected),
|
||||
[0x3f, 0xf0, 0x00, 0x00, 0x01, 0x57, 0x98, 0xef],
|
||||
"the bit representation of the result is 0x3ff00000015798ef"
|
||||
);
|
||||
// The next Number in direction -Infinity is less precise.
|
||||
assert.sameValue(nextDown(expected), 1.000000004999999_96961, "the next Number in direction -Infinity is less precise");
|
||||
// The next Number in direction +Infinity is less precise.
|
||||
assert.sameValue(nextUp(expected), 1.000000005000000_4137, "the next Number in direction +Infinity is less precise");
|
||||
|
||||
// ============
|
||||
|
||||
let relativeTo = new Temporal.ZonedDateTime(-86400_0000_0000_000_000_000n, createTimeZone(), createCalendar());
|
||||
const dYears = new Temporal.Duration(/* years = */ 1, 0, 0, /* days = */ 1, 0, 0, 0, /* milliseconds = */ 199, 0, /* nanoseconds = */ 1);
|
||||
assert.sameValue(dYears.total({ unit: "years", relativeTo }), expected, "Correct division by large number in years total");
|
||||
|
||||
relativeTo = new Temporal.ZonedDateTime(-86400_0000_0000_000_000_000n, createTimeZone(), createCalendar());
|
||||
const dMonths = new Temporal.Duration(0, /* months = */ 1, 0, /* days = */ 1, 0, 0, 0, /* milliseconds = */ 199, 0, /* nanoseconds = */ 1);
|
||||
assert.sameValue(dMonths.total({ unit: "months", relativeTo }), expected, "Correct division by large number in months total");
|
||||
|
||||
// Weeks calculation doesn't have the AddDate calls to convert months/weeks to days
|
||||
const weeksCal = new Temporal.Calendar("iso8601");
|
||||
TemporalHelpers.substituteMethod(weeksCal, "dateAdd", [
|
||||
TemporalHelpers.SUBSTITUTE_SKIP, // Duration.total step 19.a MoveRelativeZonedDateTime → AddZonedDateTime
|
||||
TemporalHelpers.SUBSTITUTE_SKIP, // RoundDuration step 7.a.i MoveRelativeZonedDateTime → AddZonedDateTime
|
||||
new Temporal.PlainDate(275760, 9, 13), // RoundDuration step 12.q MoveRelativeDate
|
||||
// sets one{Year,Month,Week}Days to 200_000_000
|
||||
]);
|
||||
relativeTo = new Temporal.ZonedDateTime(-86400_0000_0000_000_000_000n, createTimeZone(), weeksCal);
|
||||
const dWeeks = new Temporal.Duration(0, 0, /* weejs = */ 1, /* days = */ 1, 0, 0, 0, /* milliseconds = */ 199, 0, /* nanoseconds = */ 1);
|
||||
assert.sameValue(dWeeks.total({ unit: "weeks", relativeTo }), expected, "Correct division by large number in weeks total");
|
|
@ -10,6 +10,20 @@ features: [Temporal]
|
|||
const instance = new Temporal.Instant(0n);
|
||||
|
||||
const cases = [
|
||||
// 2^32 = 4294967296
|
||||
["P4294967296Y", "string with years > max"],
|
||||
[{ years: 4294967296 }, "property bag with years > max"],
|
||||
["-P4294967296Y", "string with years < min"],
|
||||
[{ years: -4294967296 }, "property bag with years < min"],
|
||||
["P4294967296M", "string with months > max"],
|
||||
[{ months: 4294967296 }, "property bag with months > max"],
|
||||
["-P4294967296M", "string with months < min"],
|
||||
[{ months: -4294967296 }, "property bag with months < min"],
|
||||
["P4294967296W", "string with weeks > max"],
|
||||
[{ weeks: 4294967296 }, "property bag with weeks > max"],
|
||||
["-P4294967296W", "string with weeks < min"],
|
||||
[{ weeks: -4294967296 }, "property bag with weeks < min"],
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
|
|
|
@ -10,6 +10,20 @@ features: [Temporal]
|
|||
const instance = new Temporal.Instant(0n);
|
||||
|
||||
const cases = [
|
||||
// 2^32 = 4294967296
|
||||
["P4294967296Y", "string with years > max"],
|
||||
[{ years: 4294967296 }, "property bag with years > max"],
|
||||
["-P4294967296Y", "string with years < min"],
|
||||
[{ years: -4294967296 }, "property bag with years < min"],
|
||||
["P4294967296M", "string with months > max"],
|
||||
[{ months: 4294967296 }, "property bag with months > max"],
|
||||
["-P4294967296M", "string with months < min"],
|
||||
[{ months: -4294967296 }, "property bag with months < min"],
|
||||
["P4294967296W", "string with weeks > max"],
|
||||
[{ weeks: 4294967296 }, "property bag with weeks > max"],
|
||||
["-P4294967296W", "string with weeks < min"],
|
||||
[{ weeks: -4294967296 }, "property bag with weeks < min"],
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
|
|
|
@ -11,6 +11,12 @@ features: [Temporal]
|
|||
const instance = new Temporal.PlainDate(1970, 1, 1);
|
||||
|
||||
const maxCases = [
|
||||
["P273790Y8M12DT23H59M59.999999999S", "string with max years"],
|
||||
[{ years: 273790, months: 8, days: 12, nanoseconds: 86399999999999 }, "property bag with max years"],
|
||||
["P3285488M12DT23H59M59.999999999S", "string with max months"],
|
||||
[{ months: 3285488, days: 12, nanoseconds: 86399999999999 }, "property bag with max months"],
|
||||
["P14285714W2DT23H59M59.999999999S", "string with max weeks"],
|
||||
[{ weeks: 14285714, days: 2, nanoseconds: 86399999999999 }, "property bag with max weeks"],
|
||||
["P100000000DT23H59M59.999999999S", "string with max days"],
|
||||
[{ days: 100000000, nanoseconds: 86399999999999 }, "property bag with max days"],
|
||||
["PT2400000023H59M59.999999999S", "string with max hours"],
|
||||
|
@ -27,6 +33,12 @@ for (const [arg, descr] of maxCases) {
|
|||
}
|
||||
|
||||
const minCases = [
|
||||
["-P273790Y8M12DT23H59M59.999999999S", "string with min years"],
|
||||
[{ years: -273790, months: -8, days: -12, nanoseconds: -86399999999999 }, "property bag with min years"],
|
||||
["-P3285488M12DT23H59M59.999999999S", "string with min months"],
|
||||
[{ months: -3285488, days: -12, nanoseconds: -86399999999999 }, "property bag with min months"],
|
||||
["-P14285714W3DT23H59M59.999999999S", "string with min weeks"],
|
||||
[{ weeks: -14285714, days: -3, nanoseconds: -86399999999999 }, "property bag with min weeks"],
|
||||
["-P100000001DT23H59M59.999999999S", "string with min days"],
|
||||
[{ days: -100000001, nanoseconds: -86399999999999 }, "property bag with min days"],
|
||||
["-PT2400000047H59M59.999999999S", "string with min hours"],
|
||||
|
|
|
@ -10,6 +10,20 @@ features: [Temporal]
|
|||
const instance = new Temporal.PlainDate(1970, 1, 1);
|
||||
|
||||
const cases = [
|
||||
// 2^32 = 4294967296
|
||||
["P4294967296Y", "string with years > max"],
|
||||
[{ years: 4294967296 }, "property bag with years > max"],
|
||||
["-P4294967296Y", "string with years < min"],
|
||||
[{ years: -4294967296 }, "property bag with years < min"],
|
||||
["P4294967296M", "string with months > max"],
|
||||
[{ months: 4294967296 }, "property bag with months > max"],
|
||||
["-P4294967296M", "string with months < min"],
|
||||
[{ months: -4294967296 }, "property bag with months < min"],
|
||||
["P4294967296W", "string with weeks > max"],
|
||||
[{ weeks: 4294967296 }, "property bag with weeks > max"],
|
||||
["-P4294967296W", "string with weeks < min"],
|
||||
[{ weeks: -4294967296 }, "property bag with weeks < min"],
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
|
|
|
@ -11,6 +11,12 @@ features: [Temporal]
|
|||
const instance = new Temporal.PlainDate(1970, 1, 1);
|
||||
|
||||
const maxCases = [
|
||||
["P273790Y8M12DT23H59M59.999999999S", "string with max years"],
|
||||
[{ years: 273790, months: 8, days: 12, nanoseconds: 86399999999999 }, "property bag with max years"],
|
||||
["P3285488M12DT23H59M59.999999999S", "string with max months"],
|
||||
[{ months: 3285488, days: 12, nanoseconds: 86399999999999 }, "property bag with max months"],
|
||||
["P14285714W3DT23H59M59.999999999S", "string with max weeks"],
|
||||
[{ weeks: 14285714, days: 3, nanoseconds: 86399999999999 }, "property bag with max weeks"],
|
||||
["P100000001DT23H59M59.999999999S", "string with max days"],
|
||||
[{ days: 100000001, nanoseconds: 86399999999999 }, "property bag with max days"],
|
||||
["PT2400000047H59M59.999999999S", "string with max hours"],
|
||||
|
@ -27,6 +33,12 @@ for (const [arg, descr] of maxCases) {
|
|||
}
|
||||
|
||||
const minCases = [
|
||||
["-P273790Y8M12DT23H59M59.999999999S", "string with min years"],
|
||||
[{ years: -273790, months: -8, days: -12, nanoseconds: -86399999999999 }, "property bag with min years"],
|
||||
["-P3285488M12DT23H59M59.999999999S", "string with min months"],
|
||||
[{ months: -3285488, days: -12, nanoseconds: -86399999999999 }, "property bag with min months"],
|
||||
["-P14285714W2DT23H59M59.999999999S", "string with min weeks"],
|
||||
[{ weeks: -14285714, days: -2, nanoseconds: -86399999999999 }, "property bag with min weeks"],
|
||||
["-P100000000DT23H59M59.999999999S", "string with min days"],
|
||||
[{ days: -100000000, nanoseconds: -86399999999999 }, "property bag with min days"],
|
||||
["-PT2400000023H59M59.999999999S", "string with min hours"],
|
||||
|
|
|
@ -10,6 +10,20 @@ features: [Temporal]
|
|||
const instance = new Temporal.PlainDate(1970, 1, 1);
|
||||
|
||||
const cases = [
|
||||
// 2^32 = 4294967296
|
||||
["P4294967296Y", "string with years > max"],
|
||||
[{ years: 4294967296 }, "property bag with years > max"],
|
||||
["-P4294967296Y", "string with years < min"],
|
||||
[{ years: -4294967296 }, "property bag with years < min"],
|
||||
["P4294967296M", "string with months > max"],
|
||||
[{ months: 4294967296 }, "property bag with months > max"],
|
||||
["-P4294967296M", "string with months < min"],
|
||||
[{ months: -4294967296 }, "property bag with months < min"],
|
||||
["P4294967296W", "string with weeks > max"],
|
||||
[{ weeks: 4294967296 }, "property bag with weeks > max"],
|
||||
["-P4294967296W", "string with weeks < min"],
|
||||
[{ weeks: -4294967296 }, "property bag with weeks < min"],
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
|
|
|
@ -11,6 +11,12 @@ features: [Temporal]
|
|||
const instance = new Temporal.PlainDateTime(1970, 1, 1);
|
||||
|
||||
const maxCases = [
|
||||
["P273790Y8M12DT23H59M59.999999999S", "string with max years"],
|
||||
[{ years: 273790, months: 8, days: 12, nanoseconds: 86399999999999 }, "property bag with max years"],
|
||||
["P3285488M12DT23H59M59.999999999S", "string with max months"],
|
||||
[{ months: 3285488, days: 12, nanoseconds: 86399999999999 }, "property bag with max months"],
|
||||
["P14285714W2DT23H59M59.999999999S", "string with max weeks"],
|
||||
[{ weeks: 14285714, days: 2, nanoseconds: 86399999999999 }, "property bag with max weeks"],
|
||||
["P100000000DT23H59M59.999999999S", "string with max days"],
|
||||
[{ days: 100000000, nanoseconds: 86399999999999 }, "property bag with max days"],
|
||||
["PT2400000023H59M59.999999999S", "string with max hours"],
|
||||
|
@ -27,6 +33,12 @@ for (const [arg, descr] of maxCases) {
|
|||
}
|
||||
|
||||
const minCases = [
|
||||
["-P273790Y8M11DT23H59M59.999999999S", "string with min years"],
|
||||
[{ years: -273790, months: -8, days: -11, nanoseconds: -86399999999999 }, "property bag with min years"],
|
||||
["-P3285488M11DT23H59M59.999999999S", "string with min months"],
|
||||
[{ months: -3285488, days: -11, nanoseconds: -86399999999999 }, "property bag with min months"],
|
||||
["-P14285714W2DT23H59M59.999999999S", "string with min weeks"],
|
||||
[{ weeks: -14285714, days: -2, nanoseconds: -86399999999999 }, "property bag with min weeks"],
|
||||
["-P100000000DT23H59M59.999999999S", "string with min days"],
|
||||
[{ days: -100000000, nanoseconds: -86399999999999 }, "property bag with min days"],
|
||||
["-PT2400000023H59M59.999999999S", "string with min hours"],
|
||||
|
|
|
@ -10,6 +10,20 @@ features: [Temporal]
|
|||
const instance = new Temporal.PlainDateTime(1970, 1, 1);
|
||||
|
||||
const cases = [
|
||||
// 2^32 = 4294967296
|
||||
["P4294967296Y", "string with years > max"],
|
||||
[{ years: 4294967296 }, "property bag with years > max"],
|
||||
["-P4294967296Y", "string with years < min"],
|
||||
[{ years: -4294967296 }, "property bag with years < min"],
|
||||
["P4294967296M", "string with months > max"],
|
||||
[{ months: 4294967296 }, "property bag with months > max"],
|
||||
["-P4294967296M", "string with months < min"],
|
||||
[{ months: -4294967296 }, "property bag with months < min"],
|
||||
["P4294967296W", "string with weeks > max"],
|
||||
[{ weeks: 4294967296 }, "property bag with weeks > max"],
|
||||
["-P4294967296W", "string with weeks < min"],
|
||||
[{ weeks: -4294967296 }, "property bag with weeks < min"],
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
|
|
|
@ -11,6 +11,12 @@ features: [Temporal]
|
|||
const instance = new Temporal.PlainDateTime(1970, 1, 1);
|
||||
|
||||
const maxCases = [
|
||||
["P273790Y8M11DT23H59M59.999999999S", "string with max years"],
|
||||
[{ years: 273790, months: 8, days: 11, nanoseconds: 86399999999999 }, "property bag with max years"],
|
||||
["P3285488M11DT23H59M59.999999999S", "string with max months"],
|
||||
[{ months: 3285488, days: 11, nanoseconds: 86399999999999 }, "property bag with max months"],
|
||||
["P14285714W2DT23H59M59.999999999S", "string with max weeks"],
|
||||
[{ weeks: 14285714, days: 2, nanoseconds: 86399999999999 }, "property bag with max weeks"],
|
||||
["P100000000DT23H59M59.999999999S", "string with max days"],
|
||||
[{ days: 100000000, nanoseconds: 86399999999999 }, "property bag with max days"],
|
||||
["PT2400000023H59M59.999999999S", "string with max hours"],
|
||||
|
@ -27,6 +33,12 @@ for (const [arg, descr] of maxCases) {
|
|||
}
|
||||
|
||||
const minCases = [
|
||||
["-P273790Y8M12DT23H59M59.999999999S", "string with min years"],
|
||||
[{ years: -273790, months: -8, days: -12, nanoseconds: -86399999999999 }, "property bag with min years"],
|
||||
["-P3285488M12DT23H59M59.999999999S", "string with min months"],
|
||||
[{ months: -3285488, days: -12, nanoseconds: -86399999999999 }, "property bag with min months"],
|
||||
["-P14285714W2DT23H59M59.999999999S", "string with min weeks"],
|
||||
[{ weeks: -14285714, days: -2, nanoseconds: -86399999999999 }, "property bag with min weeks"],
|
||||
["-P100000000DT23H59M59.999999999S", "string with min days"],
|
||||
[{ days: -100000000, nanoseconds: -86399999999999 }, "property bag with min days"],
|
||||
["-PT2400000023H59M59.999999999S", "string with min hours"],
|
||||
|
|
|
@ -10,6 +10,20 @@ features: [Temporal]
|
|||
const instance = new Temporal.PlainDateTime(1970, 1, 1);
|
||||
|
||||
const cases = [
|
||||
// 2^32 = 4294967296
|
||||
["P4294967296Y", "string with years > max"],
|
||||
[{ years: 4294967296 }, "property bag with years > max"],
|
||||
["-P4294967296Y", "string with years < min"],
|
||||
[{ years: -4294967296 }, "property bag with years < min"],
|
||||
["P4294967296M", "string with months > max"],
|
||||
[{ months: 4294967296 }, "property bag with months > max"],
|
||||
["-P4294967296M", "string with months < min"],
|
||||
[{ months: -4294967296 }, "property bag with months < min"],
|
||||
["P4294967296W", "string with weeks > max"],
|
||||
[{ weeks: 4294967296 }, "property bag with weeks > max"],
|
||||
["-P4294967296W", "string with weeks < min"],
|
||||
[{ weeks: -4294967296 }, "property bag with weeks < min"],
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
|
|
|
@ -11,6 +11,12 @@ features: [Temporal]
|
|||
const instance = new Temporal.PlainTime();
|
||||
|
||||
const maxCases = [
|
||||
["P4294967295Y104249991374DT7H36M31.999999999S", "string with max years"],
|
||||
[{ years: 4294967295, days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max years"],
|
||||
["P4294967295M104249991374DT7H36M31.999999999S", "string with max weeks"],
|
||||
[{ months: 4294967295, days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max months"],
|
||||
["P4294967295W104249991374DT7H36M31.999999999S", "string with max weeks"],
|
||||
[{ weeks: 4294967295, days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max weeks"],
|
||||
["P104249991374DT7H36M31.999999999S", "string with max days"],
|
||||
[{ days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max days"],
|
||||
["PT2501999792983H36M31.999999999S", "string with max hours"],
|
||||
|
@ -27,6 +33,12 @@ for (const [arg, descr] of maxCases) {
|
|||
}
|
||||
|
||||
const minCases = [
|
||||
["-P4294967295Y104249991374DT7H36M31.999999999S", "string with min years"],
|
||||
[{ years: -4294967295, days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min years"],
|
||||
["-P4294967295M104249991374DT7H36M31.999999999S", "string with min months"],
|
||||
[{ months: -4294967295, days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min months"],
|
||||
["-P4294967295W104249991374DT7H36M31.999999999S", "string with min weeks"],
|
||||
[{ weeks: -4294967295, days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min weeks"],
|
||||
["-P104249991374DT7H36M31.999999999S", "string with min days"],
|
||||
[{ days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min days"],
|
||||
["-PT2501999792983H36M31.999999999S", "string with min hours"],
|
||||
|
|
|
@ -10,6 +10,20 @@ features: [Temporal]
|
|||
const instance = new Temporal.PlainTime();
|
||||
|
||||
const cases = [
|
||||
// 2^32 = 4294967296
|
||||
["P4294967296Y", "string with years > max"],
|
||||
[{ years: 4294967296 }, "property bag with years > max"],
|
||||
["-P4294967296Y", "string with years < min"],
|
||||
[{ years: -4294967296 }, "property bag with years < min"],
|
||||
["P4294967296M", "string with months > max"],
|
||||
[{ months: 4294967296 }, "property bag with months > max"],
|
||||
["-P4294967296M", "string with months < min"],
|
||||
[{ months: -4294967296 }, "property bag with months < min"],
|
||||
["P4294967296W", "string with weeks > max"],
|
||||
[{ weeks: 4294967296 }, "property bag with weeks > max"],
|
||||
["-P4294967296W", "string with weeks < min"],
|
||||
[{ weeks: -4294967296 }, "property bag with weeks < min"],
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
|
|
|
@ -11,6 +11,12 @@ features: [Temporal]
|
|||
const instance = new Temporal.PlainTime();
|
||||
|
||||
const maxCases = [
|
||||
["P4294967295Y104249991374DT7H36M31.999999999S", "string with max years"],
|
||||
[{ years: 4294967295, days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max years"],
|
||||
["P4294967295M104249991374DT7H36M31.999999999S", "string with max weeks"],
|
||||
[{ months: 4294967295, days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max months"],
|
||||
["P4294967295W104249991374DT7H36M31.999999999S", "string with max weeks"],
|
||||
[{ weeks: 4294967295, days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max weeks"],
|
||||
["P104249991374DT7H36M31.999999999S", "string with max days"],
|
||||
[{ days: 104249991374, nanoseconds: 27391999999999 }, "property bag with max days"],
|
||||
["PT2501999792983H36M31.999999999S", "string with max hours"],
|
||||
|
@ -27,6 +33,12 @@ for (const [arg, descr] of maxCases) {
|
|||
}
|
||||
|
||||
const minCases = [
|
||||
["-P4294967295Y104249991374DT7H36M31.999999999S", "string with min years"],
|
||||
[{ years: -4294967295, days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min years"],
|
||||
["-P4294967295M104249991374DT7H36M31.999999999S", "string with min months"],
|
||||
[{ months: -4294967295, days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min months"],
|
||||
["-P4294967295W104249991374DT7H36M31.999999999S", "string with min weeks"],
|
||||
[{ weeks: -4294967295, days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min weeks"],
|
||||
["-P104249991374DT7H36M31.999999999S", "string with min days"],
|
||||
[{ days: -104249991374, nanoseconds: -27391999999999 }, "property bag with min days"],
|
||||
["-PT2501999792983H36M31.999999999S", "string with min hours"],
|
||||
|
|
|
@ -10,6 +10,20 @@ features: [Temporal]
|
|||
const instance = new Temporal.PlainTime();
|
||||
|
||||
const cases = [
|
||||
// 2^32 = 4294967296
|
||||
["P4294967296Y", "string with years > max"],
|
||||
[{ years: 4294967296 }, "property bag with years > max"],
|
||||
["-P4294967296Y", "string with years < min"],
|
||||
[{ years: -4294967296 }, "property bag with years < min"],
|
||||
["P4294967296M", "string with months > max"],
|
||||
[{ months: 4294967296 }, "property bag with months > max"],
|
||||
["-P4294967296M", "string with months < min"],
|
||||
[{ months: -4294967296 }, "property bag with months < min"],
|
||||
["P4294967296W", "string with weeks > max"],
|
||||
[{ weeks: 4294967296 }, "property bag with weeks > max"],
|
||||
["-P4294967296W", "string with weeks < min"],
|
||||
[{ weeks: -4294967296 }, "property bag with weeks < min"],
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
|
|
|
@ -11,6 +11,12 @@ features: [Temporal]
|
|||
const instance = new Temporal.PlainYearMonth(1970, 1);
|
||||
|
||||
const maxCases = [
|
||||
["P273790Y8M12DT23H59M59.999999999S", "string with max years"],
|
||||
[{ years: 273790, months: 8, days: 12, nanoseconds: 86399999999999 }, "property bag with max years"],
|
||||
["P3285488M12DT23H59M59.999999999S", "string with max months"],
|
||||
[{ months: 3285488, days: 12, nanoseconds: 86399999999999 }, "property bag with max months"],
|
||||
["P14285714W2DT23H59M59.999999999S", "string with max weeks"],
|
||||
[{ weeks: 14285714, days: 2, nanoseconds: 86399999999999 }, "property bag with max weeks"],
|
||||
["P100000000DT23H59M59.999999999S", "string with max days"],
|
||||
[{ days: 100000000, nanoseconds: 86399999999999 }, "property bag with max days"],
|
||||
["PT2400000023H59M59.999999999S", "string with max hours"],
|
||||
|
@ -27,6 +33,12 @@ for (const [arg, descr] of maxCases) {
|
|||
}
|
||||
|
||||
const minCases = [
|
||||
["-P273790Y8M42DT23H59M59.999999999S", "string with min years"],
|
||||
[{ years: -273790, months: -8, days: -42, nanoseconds: -86399999999999 }, "property bag with min years"],
|
||||
["-P3285488M42DT23H59M59.999999999S", "string with min months"],
|
||||
[{ months: -3285488, days: -42, nanoseconds: -86399999999999 }, "property bag with min months"],
|
||||
["-P14285718W5DT23H59M59.999999999S", "string with min weeks"],
|
||||
[{ weeks: -14285718, days: -5, nanoseconds: -86399999999999 }, "property bag with min weeks"],
|
||||
["-P100000031DT23H59M59.999999999S", "string with min days"],
|
||||
[{ days: -100000031, nanoseconds: -86399999999999 }, "property bag with min days"],
|
||||
["-PT2400000767H59M59.999999999S", "string with min hours"],
|
||||
|
|
|
@ -10,6 +10,20 @@ features: [Temporal]
|
|||
const instance = new Temporal.PlainYearMonth(1970, 1);
|
||||
|
||||
const cases = [
|
||||
// 2^32 = 4294967296
|
||||
["P4294967296Y", "string with years > max"],
|
||||
[{ years: 4294967296 }, "property bag with years > max"],
|
||||
["-P4294967296Y", "string with years < min"],
|
||||
[{ years: -4294967296 }, "property bag with years < min"],
|
||||
["P4294967296M", "string with months > max"],
|
||||
[{ months: 4294967296 }, "property bag with months > max"],
|
||||
["-P4294967296M", "string with months < min"],
|
||||
[{ months: -4294967296 }, "property bag with months < min"],
|
||||
["P4294967296W", "string with weeks > max"],
|
||||
[{ weeks: 4294967296 }, "property bag with weeks > max"],
|
||||
["-P4294967296W", "string with weeks < min"],
|
||||
[{ weeks: -4294967296 }, "property bag with weeks < min"],
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
|
|
|
@ -11,6 +11,12 @@ features: [Temporal]
|
|||
const instance = new Temporal.PlainYearMonth(1970, 1);
|
||||
|
||||
const maxCases = [
|
||||
["P273790Y8M42DT23H59M59.999999999S", "string with max years"],
|
||||
[{ years: 273790, months: 8, days: 42, nanoseconds: 86399999999999 }, "property bag with max years"],
|
||||
["P3285488M42DT23H59M59.999999999S", "string with max months"],
|
||||
[{ months: 3285488, days: 42, nanoseconds: 86399999999999 }, "property bag with max months"],
|
||||
["P14285718W5DT23H59M59.999999999S", "string with max weeks"],
|
||||
[{ weeks: 14285718, days: 5, nanoseconds: 86399999999999 }, "property bag with max weeks"],
|
||||
["P100000031DT23H59M59.999999999S", "string with max days"],
|
||||
[{ days: 100000031, nanoseconds: 86399999999999 }, "property bag with max days"],
|
||||
["PT2400000767H59M59.999999999S", "string with max hours"],
|
||||
|
@ -27,6 +33,12 @@ for (const [arg, descr] of maxCases) {
|
|||
}
|
||||
|
||||
const minCases = [
|
||||
["-P273790Y8M12DT23H59M59.999999999S", "string with min years"],
|
||||
[{ years: -273790, months: -8, days: -12, nanoseconds: -86399999999999 }, "property bag with min years"],
|
||||
["-P3285488M12DT23H59M59.999999999S", "string with min months"],
|
||||
[{ months: -3285488, days: -12, nanoseconds: -86399999999999 }, "property bag with min months"],
|
||||
["-P14285714W2DT23H59M59.999999999S", "string with min weeks"],
|
||||
[{ weeks: -14285714, days: -2, nanoseconds: -86399999999999 }, "property bag with min weeks"],
|
||||
["-P100000000DT23H59M59.999999999S", "string with min days"],
|
||||
[{ days: -100000000, nanoseconds: -86399999999999 }, "property bag with min days"],
|
||||
["-PT2400000023H59M59.999999999S", "string with min hours"],
|
||||
|
|
|
@ -10,6 +10,20 @@ features: [Temporal]
|
|||
const instance = new Temporal.PlainYearMonth(1970, 1);
|
||||
|
||||
const cases = [
|
||||
// 2^32 = 4294967296
|
||||
["P4294967296Y", "string with years > max"],
|
||||
[{ years: 4294967296 }, "property bag with years > max"],
|
||||
["-P4294967296Y", "string with years < min"],
|
||||
[{ years: -4294967296 }, "property bag with years < min"],
|
||||
["P4294967296M", "string with months > max"],
|
||||
[{ months: 4294967296 }, "property bag with months > max"],
|
||||
["-P4294967296M", "string with months < min"],
|
||||
[{ months: -4294967296 }, "property bag with months < min"],
|
||||
["P4294967296W", "string with weeks > max"],
|
||||
[{ weeks: 4294967296 }, "property bag with weeks > max"],
|
||||
["-P4294967296W", "string with weeks < min"],
|
||||
[{ weeks: -4294967296 }, "property bag with weeks < min"],
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
|
|
|
@ -10,6 +10,12 @@ features: [Temporal]
|
|||
const instance = new Temporal.ZonedDateTime(0n, "UTC");
|
||||
|
||||
const maxCases = [
|
||||
["P273790Y8M12D", "string with max years"],
|
||||
[{ years: 273790, months: 8, days: 12 }, "property bag with max years"],
|
||||
["P3285488M12D", "string with max months"],
|
||||
[{ months: 3285488, days: 12 }, "property bag with max months"],
|
||||
["P14285714W2D", "string with max weeks"],
|
||||
[{ weeks: 14285714, days: 2 }, "property bag with max weeks"],
|
||||
["P100000000D", "string with max days"],
|
||||
[{ days: 100000000 }, "property bag with max days"],
|
||||
["PT2400000000H", "string with max hours"],
|
||||
|
@ -26,6 +32,12 @@ for (const [arg, descr] of maxCases) {
|
|||
}
|
||||
|
||||
const minCases = [
|
||||
["-P273790Y8M11D", "string with min years"],
|
||||
[{ years: -273790, months: -8, days: -11 }, "property bag with min years"],
|
||||
["-P3285488M11D", "string with min months"],
|
||||
[{ months: -3285488, days: -11 }, "property bag with min months"],
|
||||
["-P14285714W2D", "string with min weeks"],
|
||||
[{ weeks: -14285714, days: -2 }, "property bag with min weeks"],
|
||||
["-P100000000D", "string with min days"],
|
||||
[{ days: -100000000 }, "property bag with min days"],
|
||||
["-PT2400000000H", "string with min hours"],
|
||||
|
|
|
@ -10,6 +10,20 @@ features: [Temporal]
|
|||
const instance = new Temporal.ZonedDateTime(0n, "UTC");
|
||||
|
||||
const cases = [
|
||||
// 2^32 = 4294967296
|
||||
["P4294967296Y", "string with years > max"],
|
||||
[{ years: 4294967296 }, "property bag with years > max"],
|
||||
["-P4294967296Y", "string with years < min"],
|
||||
[{ years: -4294967296 }, "property bag with years < min"],
|
||||
["P4294967296M", "string with months > max"],
|
||||
[{ months: 4294967296 }, "property bag with months > max"],
|
||||
["-P4294967296M", "string with months < min"],
|
||||
[{ months: -4294967296 }, "property bag with months < min"],
|
||||
["P4294967296W", "string with weeks > max"],
|
||||
[{ weeks: 4294967296 }, "property bag with weeks > max"],
|
||||
["-P4294967296W", "string with weeks < min"],
|
||||
[{ weeks: -4294967296 }, "property bag with weeks < min"],
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
|
|
|
@ -10,6 +10,12 @@ features: [Temporal]
|
|||
const instance = new Temporal.ZonedDateTime(0n, "UTC");
|
||||
|
||||
const maxCases = [
|
||||
["P273790Y8M11D", "string with max years"],
|
||||
[{ years: 273790, months: 8, days: 11 }, "property bag with max years"],
|
||||
["P3285488M11D", "string with max months"],
|
||||
[{ months: 3285488, days: 11 }, "property bag with max months"],
|
||||
["P14285714W2D", "string with max weeks"],
|
||||
[{ weeks: 14285714, days: 2 }, "property bag with max weeks"],
|
||||
["P100000000D", "string with max days"],
|
||||
[{ days: 100000000 }, "property bag with max days"],
|
||||
["PT2400000000H", "string with max hours"],
|
||||
|
@ -26,6 +32,12 @@ for (const [arg, descr] of maxCases) {
|
|||
}
|
||||
|
||||
const minCases = [
|
||||
["-P273790Y8M12D", "string with min years"],
|
||||
[{ years: -273790, months: -8, days: -12 }, "property bag with min years"],
|
||||
["-P3285488M12D", "string with min months"],
|
||||
[{ months: -3285488, days: -12 }, "property bag with min months"],
|
||||
["-P14285714W2D", "string with min weeks"],
|
||||
[{ weeks: -14285714, days: -2 }, "property bag with min weeks"],
|
||||
["-P100000000D", "string with min days"],
|
||||
[{ days: -100000000 }, "property bag with min days"],
|
||||
["-PT2400000000H", "string with min hours"],
|
||||
|
|
|
@ -10,6 +10,20 @@ features: [Temporal]
|
|||
const instance = new Temporal.ZonedDateTime(0n, "UTC");
|
||||
|
||||
const cases = [
|
||||
// 2^32 = 4294967296
|
||||
["P4294967296Y", "string with years > max"],
|
||||
[{ years: 4294967296 }, "property bag with years > max"],
|
||||
["-P4294967296Y", "string with years < min"],
|
||||
[{ years: -4294967296 }, "property bag with years < min"],
|
||||
["P4294967296M", "string with months > max"],
|
||||
[{ months: 4294967296 }, "property bag with months > max"],
|
||||
["-P4294967296M", "string with months < min"],
|
||||
[{ months: -4294967296 }, "property bag with months < min"],
|
||||
["P4294967296W", "string with weeks > max"],
|
||||
[{ weeks: 4294967296 }, "property bag with weeks > max"],
|
||||
["-P4294967296W", "string with weeks < min"],
|
||||
[{ weeks: -4294967296 }, "property bag with weeks < min"],
|
||||
|
||||
// ceil(max safe integer / 86400) = 104249991375
|
||||
["P104249991375D", "string with days > max"],
|
||||
[{ days: 104249991375 }, "property bag with days > max"],
|
||||
|
|
|
@ -32,46 +32,3 @@ units.forEach(unit => assert.sameValue(`${ Temporal.Duration.from({ [unit]: 0 })
|
|||
"PT0M",
|
||||
"PT0S"
|
||||
].forEach(str => assert.sameValue(`${ Temporal.Duration.from(str) }`, "PT0S"));
|
||||
|
||||
// unrepresentable number is not allowed
|
||||
units.forEach((unit, ix) => {
|
||||
assert.throws(RangeError, () => new Temporal.Duration(...Array(ix).fill(0), 1e+400));
|
||||
assert.throws(RangeError, () => Temporal.Duration.from({ [unit]: 1e+400 }));
|
||||
});
|
||||
var manyNines = "9".repeat(309);
|
||||
[
|
||||
`P${ manyNines }Y`,
|
||||
`P${ manyNines }M`,
|
||||
`P${ manyNines }W`,
|
||||
`P${ manyNines }D`,
|
||||
`PT${ manyNines }H`,
|
||||
`PT${ manyNines }M`,
|
||||
`PT${ manyNines }S`
|
||||
].forEach(str => assert.throws(RangeError, () => Temporal.Duration.from(str)));
|
||||
|
||||
// max safe integer is allowed in calendar units and as seconds
|
||||
[
|
||||
[0, "P9007199254740991Y"],
|
||||
[1, "P9007199254740991M"],
|
||||
[2, "P9007199254740991W"],
|
||||
[6, "PT9007199254740991S"],
|
||||
].forEach(([ix, str]) => {
|
||||
assert.sameValue(`${ new Temporal.Duration(...Array(ix).fill(0), Number.MAX_SAFE_INTEGER) }`, str);
|
||||
assert.sameValue(`${ Temporal.Duration.from(str) }`, str);
|
||||
});
|
||||
|
||||
// larger integers are allowed in calendar units but may lose precision
|
||||
function test(ix, suffix) {
|
||||
function doAsserts(duration) {
|
||||
var str = duration.toString();
|
||||
assert.sameValue(str.slice(0, 11), "P1000000000");
|
||||
assert.sameValue(str.slice(-1), suffix);
|
||||
assert.sameValue(str.length, suffix.length + 28);
|
||||
}
|
||||
doAsserts(new Temporal.Duration(...Array(ix).fill(0), 1e+26, ...Array(9 - ix).fill(0)));
|
||||
doAsserts(Temporal.Duration.from({ [units[ix]]: 1e+26 }));
|
||||
doAsserts(Temporal.Duration.from(`P100000000000001000000000000${ suffix }`));
|
||||
}
|
||||
test(0, "Y");
|
||||
test(1, "M");
|
||||
test(2, "W");
|
||||
|
|
Loading…
Reference in New Issue