mirror of https://github.com/tc39/test262.git
Import SpiderMonkey Temporal tests
Temporal tests written for the SpiderMonkey implementation. Mostly covers edge cases around mathematical operations and regression tests for reported spec bugs.
This commit is contained in:
parent
91a61b29ac
commit
a3040a5047
|
@ -0,0 +1,33 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.calendar.prototype.dateadd
|
||||
description: >
|
||||
Call BalanceISOYearMonth with Number.MAX_VALUE and -Number.MAX_VALUE for years/months.
|
||||
info: |
|
||||
Temporal.Calendar.prototype.dateAdd ( date, duration [ , options ] )
|
||||
|
||||
...
|
||||
9. Let result be ? AddISODate(date.[[ISOYear]], date.[[ISOMonth]], date.[[ISODay]],
|
||||
duration.[[Years]], duration.[[Months]], duration.[[Weeks]], balanceResult.[[Days]],
|
||||
overflow).
|
||||
10. Return ? CreateTemporalDate(result.[[Year]], result.[[Month]], result.[[Day]], calendar).
|
||||
|
||||
AddISODate ( year, month, day, years, months, weeks, days, overflow )
|
||||
|
||||
...
|
||||
3. Let intermediate be ! BalanceISOYearMonth(year + years, month + months).
|
||||
...
|
||||
|
||||
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);
|
||||
|
||||
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");
|
18
test/built-ins/Temporal/Duration/prototype/add/days-is-number-max-value-with-zoneddatetime.js
vendored
Normal file
18
test/built-ins/Temporal/Duration/prototype/add/days-is-number-max-value-with-zoneddatetime.js
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.add
|
||||
description: >
|
||||
AddZonedDateTime throws a RangeError when the intermediate instant is too large.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const plainDate = new Temporal.PlainDate(1970, 1, 1);
|
||||
const zonedDateTime = new Temporal.ZonedDateTime(0n, "UTC", "iso8601");
|
||||
|
||||
var duration = Temporal.Duration.from({days: 1, nanoseconds: Number.MAX_VALUE});
|
||||
|
||||
var options = {relativeTo: zonedDateTime};
|
||||
|
||||
assert.throws(RangeError, () => duration.add(duration, options));
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.add
|
||||
description: >
|
||||
BalanceDuration throws a RangeError when the result is too large.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
var duration = Temporal.Duration.from({days: Number.MAX_VALUE});
|
||||
|
||||
assert.throws(RangeError, () => duration.add(duration));
|
27
test/built-ins/Temporal/Duration/prototype/add/nanoseconds-is-number-max-value-1.js
vendored
Normal file
27
test/built-ins/Temporal/Duration/prototype/add/nanoseconds-is-number-max-value-1.js
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.add
|
||||
description: >
|
||||
BalanceDuration throws a RangeError when the result is too large.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const plainDate = new Temporal.PlainDate(1970, 1, 1);
|
||||
const zonedDateTime = new Temporal.ZonedDateTime(0n, "UTC", "iso8601");
|
||||
|
||||
// Largest temporal unit is "nanosecond".
|
||||
const duration = Temporal.Duration.from({nanoseconds: Number.MAX_VALUE});
|
||||
|
||||
assert.throws(RangeError, () => {
|
||||
duration.add(duration);
|
||||
});
|
||||
|
||||
assert.throws(RangeError, () => {
|
||||
duration.add(duration, {relativeTo: plainDate});
|
||||
});
|
||||
|
||||
assert.throws(RangeError, () => {
|
||||
duration.add(duration, {relativeTo: zonedDateTime});
|
||||
});
|
72
test/built-ins/Temporal/Duration/prototype/round/nanoseconds-to-days-loop-indefinitely-1.js
vendored
Normal file
72
test/built-ins/Temporal/Duration/prototype/round/nanoseconds-to-days-loop-indefinitely-1.js
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.round
|
||||
description: >
|
||||
NanosecondsToDays can loop indefinitely.
|
||||
info: |
|
||||
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||
|
||||
...
|
||||
15. If sign is 1, then
|
||||
a. Repeat, while days > 0 and intermediateNs > endNs,
|
||||
i. Set days to days - 1.
|
||||
ii. Set intermediateNs to ℝ(? AddZonedDateTime(ℤ(startNs), relativeTo.[[TimeZone]],
|
||||
relativeTo.[[Calendar]], 0, 0, 0, days, 0, 0, 0, 0, 0, 0)).
|
||||
...
|
||||
includes: [temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Intentionally not Test262Error to ensure assertion errors are correctly propagated.
|
||||
class StopExecution extends Error {}
|
||||
|
||||
const stopAt = 1000;
|
||||
|
||||
// Always add two days to the start date, this ensures the intermediate date
|
||||
// is larger than the end date.
|
||||
let twoDays = Temporal.Duration.from({days: 2});
|
||||
|
||||
// Number of calls to dateAdd.
|
||||
let count = 0;
|
||||
|
||||
let cal = new class extends Temporal.Calendar {
|
||||
// Set `days` to a number larger than `Number.MAX_SAFE_INTEGER`.
|
||||
dateUntil(start, end, options) {
|
||||
return Temporal.Duration.from({days: Number.MAX_VALUE});
|
||||
}
|
||||
|
||||
dateAdd(date, duration, options) {
|
||||
// Stop when we've reached the test limit.
|
||||
count += 1;
|
||||
if (count === stopAt) {
|
||||
throw new StopExecution();
|
||||
}
|
||||
|
||||
if (count === 1) {
|
||||
return Temporal.Calendar.prototype.dateAdd.call(this, date, duration, options);
|
||||
}
|
||||
|
||||
TemporalHelpers.assertPlainDate(date, 1970, 1, "M01", 1);
|
||||
|
||||
TemporalHelpers.assertDuration(
|
||||
duration,
|
||||
0, 0, 0, Number.MAX_VALUE,
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
);
|
||||
|
||||
return Temporal.Calendar.prototype.dateAdd.call(this, date, twoDays, options);
|
||||
}
|
||||
}("iso8601");
|
||||
|
||||
let zdt = new Temporal.ZonedDateTime(0n, "UTC", cal);
|
||||
let duration = Temporal.Duration.from({days: 1});
|
||||
let options = {
|
||||
largestUnit: "days",
|
||||
relativeTo: zdt,
|
||||
};
|
||||
|
||||
assert.throws(StopExecution, () => duration.round(options));
|
||||
assert.sameValue(count, stopAt);
|
65
test/built-ins/Temporal/Duration/prototype/round/nanoseconds-to-days-loop-indefinitely-2.js
vendored
Normal file
65
test/built-ins/Temporal/Duration/prototype/round/nanoseconds-to-days-loop-indefinitely-2.js
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.round
|
||||
description: >
|
||||
NanosecondsToDays can loop indefinitely.
|
||||
info: |
|
||||
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||
|
||||
...
|
||||
18. Repeat, while done is false,
|
||||
a. Let oneDayFartherNs be ℝ(? AddZonedDateTime(ℤ(intermediateNs), relativeTo.[[TimeZone]],
|
||||
relativeTo.[[Calendar]], 0, 0, 0, sign, 0, 0, 0, 0, 0, 0)).
|
||||
b. Set dayLengthNs to oneDayFartherNs - intermediateNs.
|
||||
c. If (nanoseconds - dayLengthNs) × sign ≥ 0, then
|
||||
i. Set nanoseconds to nanoseconds - dayLengthNs.
|
||||
ii. Set intermediateNs to oneDayFartherNs.
|
||||
iii. Set days to days + sign.
|
||||
d. Else,
|
||||
i. Set done to true.
|
||||
includes: [temporalHelpers.js]
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Intentionally not Test262Error to ensure assertion errors are correctly propagated.
|
||||
class StopExecution extends Error {}
|
||||
|
||||
const stopAt = 1000;
|
||||
|
||||
// Number of calls to getPossibleInstantsFor.
|
||||
let count = 0;
|
||||
|
||||
// UTC time zones so we don't have to worry about time zone offsets.
|
||||
let tz = new class extends Temporal.TimeZone {
|
||||
getPossibleInstantsFor(dt) {
|
||||
// Stop when we've reached the test limit.
|
||||
count += 1;
|
||||
if (count === stopAt) {
|
||||
throw new StopExecution();
|
||||
}
|
||||
|
||||
if (count < 4) {
|
||||
// The first couple calls request the instant for 1970-01-02.
|
||||
TemporalHelpers.assertPlainDateTime(dt, 1970, 1, "M01", 2, 0, 0, 0, 0, 0, 0);
|
||||
} else {
|
||||
// Later on the instant for 1970-01-03 is requested.
|
||||
TemporalHelpers.assertPlainDateTime(dt, 1970, 1, "M01", 3, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
// Always return "1970-01-02T00:00:00Z". This leads to iterating indefinitely
|
||||
// in NanosecondsToDays.
|
||||
return [new Temporal.Instant(86400000000000n)];
|
||||
}
|
||||
}("UTC");
|
||||
|
||||
let zdt = new Temporal.ZonedDateTime(0n, tz);
|
||||
let duration = Temporal.Duration.from({days: 1});
|
||||
let options = {
|
||||
smallestUnit: "days",
|
||||
relativeTo: zdt,
|
||||
};
|
||||
|
||||
assert.throws(StopExecution, () => duration.round(options));
|
||||
assert.sameValue(count, stopAt);
|
27
test/built-ins/Temporal/Duration/prototype/round/number-max-value-too-large.js
vendored
Normal file
27
test/built-ins/Temporal/Duration/prototype/round/number-max-value-too-large.js
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.round
|
||||
description: >
|
||||
RoundDuration throws a RangeError when the result duration is invalid.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
function test(unit, nextSmallestUnit) {
|
||||
var duration = Temporal.Duration.from({
|
||||
[unit]: Number.MAX_VALUE,
|
||||
[nextSmallestUnit]: Number.MAX_VALUE,
|
||||
});
|
||||
|
||||
var options = {smallestUnit: unit, largestUnit: unit};
|
||||
|
||||
assert.throws(RangeError, () => duration.round(options));
|
||||
}
|
||||
|
||||
test("days", "hours");
|
||||
test("hours", "minutes");
|
||||
test("minutes", "seconds");
|
||||
test("seconds", "milliseconds");
|
||||
test("milliseconds", "microseconds");
|
||||
test("microseconds", "nanoseconds");
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.round
|
||||
description: >
|
||||
BalanceDuration throws when the duration signs don't match.
|
||||
info: |
|
||||
BalanceDuration ( days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds,
|
||||
largestUnit [ , relativeTo ] )
|
||||
|
||||
...
|
||||
4. If largestUnit is one of "year", "month", "week", or "day", then
|
||||
a. Let result be ? NanosecondsToDays(nanoseconds, relativeTo).
|
||||
b. Set days to result.[[Days]].
|
||||
c. Set nanoseconds to result.[[Nanoseconds]].
|
||||
...
|
||||
15. Return ? CreateTimeDurationRecord(days, hours × sign, minutes × sign, seconds × sign,
|
||||
milliseconds × sign, microseconds × sign, nanoseconds × sign).
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
let duration = Temporal.Duration.from({
|
||||
hours: -(24 * 1),
|
||||
nanoseconds: -1,
|
||||
});
|
||||
|
||||
let tz = new class extends Temporal.TimeZone {
|
||||
#getPossibleInstantsFor = 0;
|
||||
|
||||
getPossibleInstantsFor(dt) {
|
||||
this.#getPossibleInstantsFor++;
|
||||
|
||||
if (this.#getPossibleInstantsFor === 1) {
|
||||
return [new Temporal.Instant(-86400_000_000_000n - 2n)]
|
||||
}
|
||||
return super.getPossibleInstantsFor(dt);
|
||||
}
|
||||
}("UTC");
|
||||
|
||||
let zdt = new Temporal.ZonedDateTime(0n, tz, "iso8601");
|
||||
|
||||
let options = {
|
||||
relativeTo: zdt,
|
||||
largestUnit: "days",
|
||||
};
|
||||
|
||||
assert.throws(RangeError, () => duration.round(options));
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.round
|
||||
description: >
|
||||
UnbalanceDurationRelative throws a RangeError when duration signs don't match.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
var duration = Temporal.Duration.from({
|
||||
years: 1,
|
||||
months: 0,
|
||||
weeks: 1,
|
||||
});
|
||||
|
||||
var cal = new class extends Temporal.Calendar {
|
||||
dateUntil(one, two, options) {
|
||||
var result = super.dateUntil(one, two, options);
|
||||
return result.negated();
|
||||
}
|
||||
}("iso8601");
|
||||
|
||||
var relativeTo = new Temporal.PlainDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0, cal);
|
||||
assert.sameValue(relativeTo.calendar, cal);
|
||||
|
||||
var options = {
|
||||
smallestUnit: "days",
|
||||
largestUnit: "month",
|
||||
relativeTo,
|
||||
};
|
||||
|
||||
assert.throws(RangeError, () => duration.round(options));
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.round
|
||||
description: >
|
||||
NanosecondsToDays throws a RangeError when the number of nanoseconds is too large.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
var duration = Temporal.Duration.from({
|
||||
nanoseconds: Number.MAX_VALUE,
|
||||
});
|
||||
|
||||
var zonedDateTime = new Temporal.ZonedDateTime(0n, "UTC");
|
||||
|
||||
var options = {
|
||||
smallestUnit: "day",
|
||||
largestUnit: "day",
|
||||
relativeTo: zonedDateTime,
|
||||
};
|
||||
|
||||
assert.throws(RangeError, () => duration.round(options));
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.subtract
|
||||
description: >
|
||||
AddZonedDateTime throws a RangeError when the intermediate instant is too large.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const plainDate = new Temporal.PlainDate(1970, 1, 1);
|
||||
const zonedDateTime = new Temporal.ZonedDateTime(0n, "UTC", "iso8601");
|
||||
|
||||
var duration1 = Temporal.Duration.from({days: 1, nanoseconds: Number.MAX_VALUE});
|
||||
var duration2 = Temporal.Duration.from({days: -1, nanoseconds: -Number.MAX_VALUE});
|
||||
|
||||
var options = {relativeTo: zonedDateTime};
|
||||
|
||||
assert.throws(RangeError, () => duration1.subtract(duration2, options));
|
14
test/built-ins/Temporal/Duration/prototype/subtract/days-is-number-max-value.js
vendored
Normal file
14
test/built-ins/Temporal/Duration/prototype/subtract/days-is-number-max-value.js
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.subtract
|
||||
description: >
|
||||
BalanceDuration throws a RangeError when the result is too large.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
var duration1 = Temporal.Duration.from({days: Number.MAX_VALUE});
|
||||
var duration2 = Temporal.Duration.from({days: -Number.MAX_VALUE});
|
||||
|
||||
assert.throws(RangeError, () => duration1.subtract(duration2));
|
28
test/built-ins/Temporal/Duration/prototype/subtract/nanoseconds-is-number-max-value-1.js
vendored
Normal file
28
test/built-ins/Temporal/Duration/prototype/subtract/nanoseconds-is-number-max-value-1.js
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.subtract
|
||||
description: >
|
||||
BalanceDuration throws a RangeError when the result is too large.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const plainDate = new Temporal.PlainDate(1970, 1, 1);
|
||||
const zonedDateTime = new Temporal.ZonedDateTime(0n, "UTC", "iso8601");
|
||||
|
||||
// Largest temporal unit is "nanosecond".
|
||||
const duration1 = Temporal.Duration.from({nanoseconds: Number.MAX_VALUE});
|
||||
const duration2 = Temporal.Duration.from({nanoseconds: -Number.MAX_VALUE});
|
||||
|
||||
assert.throws(RangeError, () => {
|
||||
duration1.subtract(duration2);
|
||||
});
|
||||
|
||||
assert.throws(RangeError, () => {
|
||||
duration1.subtract(duration2, {relativeTo: plainDate});
|
||||
});
|
||||
|
||||
assert.throws(RangeError, () => {
|
||||
duration1.subtract(duration2, {relativeTo: zonedDateTime});
|
||||
});
|
44
test/built-ins/Temporal/Duration/prototype/toString/precision-formatted-as-decimal-number.js
vendored
Normal file
44
test/built-ins/Temporal/Duration/prototype/toString/precision-formatted-as-decimal-number.js
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
// 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");
|
||||
}
|
45
test/built-ins/Temporal/Duration/prototype/toString/throws-when-rounded-duration-is-invalid.js
vendored
Normal file
45
test/built-ins/Temporal/Duration/prototype/toString/throws-when-rounded-duration-is-invalid.js
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.tostring
|
||||
description: >
|
||||
RoundDuration throws when the rounded duration can't be represented using
|
||||
float64-representable integers.
|
||||
info: |
|
||||
Temporal.Duration.prototype.toString ( [ options ] )
|
||||
|
||||
...
|
||||
7. Let result be (? RoundDuration(...)).[[DurationRecord]].
|
||||
...
|
||||
|
||||
RoundDuration ( years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds,
|
||||
nanoseconds, increment, unit, roundingMode [ , relativeTo ] )
|
||||
|
||||
...
|
||||
15. Else if unit is "second", then
|
||||
a. Set seconds to RoundNumberToIncrement(fractionalSeconds, increment, roundingMode).
|
||||
b. Set remainder to fractionalSeconds - seconds.
|
||||
c. Set milliseconds, microseconds, and nanoseconds to 0.
|
||||
...
|
||||
19. Let duration be ? CreateDurationRecord(years, months, weeks, days, hours, minutes, seconds,
|
||||
milliseconds, microseconds, nanoseconds).
|
||||
...
|
||||
|
||||
CreateDurationRecord ( years, months, weeks, days, hours, minutes, seconds, milliseconds,
|
||||
microseconds, nanoseconds )
|
||||
|
||||
1. If ! IsValidDuration(years, months, weeks, days, hours, minutes, seconds, milliseconds,
|
||||
microseconds, nanoseconds) is false, throw a RangeError exception.
|
||||
...
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
var duration = Temporal.Duration.from({
|
||||
seconds: Number.MAX_VALUE,
|
||||
milliseconds: Number.MAX_VALUE,
|
||||
});
|
||||
|
||||
var options = {smallestUnit: "seconds"};
|
||||
|
||||
assert.throws(RangeError, () => duration.toString(options));
|
23
test/built-ins/Temporal/Duration/prototype/total/relativeto-string-plaindatetime-invalid.js
vendored
Normal file
23
test/built-ins/Temporal/Duration/prototype/total/relativeto-string-plaindatetime-invalid.js
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.total
|
||||
description: >
|
||||
Throws a RangeError if "relativeTo" is a date/time value outside the valid limits.
|
||||
info: |
|
||||
Temporal.Duration.prototype.total ( totalOf )
|
||||
...
|
||||
6. Let relativeTo be ? ToRelativeTemporalObject(totalOf).
|
||||
...
|
||||
|
||||
ToRelativeTemporalObject ( options )
|
||||
...
|
||||
9. Return ? CreateTemporalDate(result.[[Year]], result.[[Month]], result.[[Day]], calendar).
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
var duration = Temporal.Duration.from({nanoseconds: 0});
|
||||
var options = {unit: "nanoseconds", relativeTo: "+999999-01-01"};
|
||||
|
||||
assert.throws(RangeError, () => duration.total(options));
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.total
|
||||
description: >
|
||||
Relative to a ZonedDateTime with a fractional number of days and different sign.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
let duration = Temporal.Duration.from({
|
||||
weeks: 1,
|
||||
days: 0,
|
||||
hours: 1,
|
||||
});
|
||||
|
||||
let cal = new class extends Temporal.Calendar {
|
||||
#dateAdd = 0;
|
||||
|
||||
dateAdd(date, duration, options) {
|
||||
if (++this.#dateAdd === 1) {
|
||||
duration = "-P1W";
|
||||
}
|
||||
return super.dateAdd(date, duration, options);
|
||||
}
|
||||
}("iso8601");
|
||||
|
||||
let zdt = new Temporal.ZonedDateTime(0n, "UTC", cal);
|
||||
|
||||
let result = duration.total({
|
||||
relativeTo: zdt,
|
||||
unit: "days",
|
||||
});
|
||||
|
||||
assert.sameValue(result, -7 + 1 / 24);
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.total
|
||||
description: >
|
||||
Relative to a ZonedDateTime with a fractional number of days.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
let duration = Temporal.Duration.from({
|
||||
weeks: 1,
|
||||
days: 0,
|
||||
hours: 1,
|
||||
});
|
||||
|
||||
let zdt = new Temporal.ZonedDateTime(0n, "UTC", "iso8601");
|
||||
|
||||
let result = duration.total({
|
||||
relativeTo: zdt,
|
||||
unit: "days",
|
||||
});
|
||||
|
||||
assert.sameValue(result, 7 + 1 / 24);
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.instant.compare
|
||||
description: >
|
||||
Throws when argument at maximum representable date/time value with a negative offset.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Not a valid epoch nanoseconds value due to the offset.
|
||||
var one = "+275760-09-13T00:00:00.000-12";
|
||||
|
||||
var two = {
|
||||
toString() {
|
||||
throw new Test262Error();
|
||||
}
|
||||
};
|
||||
|
||||
assert.throws(RangeError, () => Temporal.Instant.compare(one, two));
|
45
test/built-ins/Temporal/PlainDateTime/prototype/since/balance-infinite-nanoseconds-duration.js
vendored
Normal file
45
test/built-ins/Temporal/PlainDateTime/prototype/since/balance-infinite-nanoseconds-duration.js
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaindatetime.prototype.since
|
||||
description: >
|
||||
BalanceDuration throws when the result duration is invalid.
|
||||
info: |
|
||||
DifferenceISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1,
|
||||
y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2,
|
||||
calendar, largestUnit, options )
|
||||
|
||||
...
|
||||
12. Let dateDifference be ? CalendarDateUntil(calendar, date1, date2, untilOptions).
|
||||
13. Let balanceResult be ? BalanceDuration(dateDifference.[[Days]], timeDifference.[[Hours]],
|
||||
timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]],
|
||||
timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]], largestUnit).
|
||||
...
|
||||
|
||||
BalanceDuration ( days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds,
|
||||
largestUnit [ , relativeTo ] )
|
||||
|
||||
...
|
||||
3. Else,
|
||||
a. Set nanoseconds to ! TotalDurationNanoseconds(days, hours, minutes, seconds, milliseconds,
|
||||
microseconds, nanoseconds, 0).
|
||||
...
|
||||
15. Return ? CreateTimeDurationRecord(days, hours × sign, minutes × sign, seconds × sign,
|
||||
milliseconds × sign, microseconds × sign, nanoseconds × sign).
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
var cal = new class extends Temporal.Calendar {
|
||||
dateUntil(date1, date2, options) {
|
||||
return Temporal.Duration.from({days: Number.MAX_VALUE});
|
||||
}
|
||||
}("iso8601");
|
||||
|
||||
var dt1 = new Temporal.PlainDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0, cal);
|
||||
var dt2 = new Temporal.PlainDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0, cal);
|
||||
var options = {largestUnit: "nanoseconds"};
|
||||
|
||||
assert.throws(RangeError, () => dt1.since(dt1, options));
|
||||
assert.throws(RangeError, () => dt1.since(dt2, options));
|
||||
assert.throws(RangeError, () => dt2.since(dt1, options));
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaindatetime.prototype.tozoneddatetime
|
||||
description: >
|
||||
Throws when at minimum resp. maximum value and possible instants is an empty List.
|
||||
info: |
|
||||
DisambiguatePossibleInstants ( possibleInstants, timeZone, dateTime, disambiguation )
|
||||
|
||||
...
|
||||
9. If ! IsValidEpochNanoseconds(dayBeforeNs) is false, throw a RangeError exception.
|
||||
...
|
||||
12. If ! IsValidEpochNanoseconds(dayAfterNs) is false, throw a RangeError exception.
|
||||
...
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
class TZ extends Temporal.TimeZone {
|
||||
getPossibleInstantsFor() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
var tz = new TZ("UTC");
|
||||
var min = new Temporal.PlainDateTime(-271821, 4, 20);
|
||||
var max = new Temporal.PlainDateTime(275760, 9, 13);
|
||||
|
||||
assert.throws(RangeError, () => min.toZonedDateTime(tz), "minimum date-time");
|
||||
assert.throws(RangeError, () => max.toZonedDateTime(tz), "maximum date-time");
|
34
test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/plain-date-time-near-limits.js
vendored
Normal file
34
test/built-ins/Temporal/PlainDateTime/prototype/toZonedDateTime/plain-date-time-near-limits.js
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaindatetime.prototype.tozoneddatetime
|
||||
description: >
|
||||
Throws a RangeError if the date/time value is outside the instant limits
|
||||
info: |
|
||||
Temporal.PlainDateTime.prototype.toZonedDateTime ( temporalTimeZoneLike [ , options ] )
|
||||
...
|
||||
6. Let instant be ? BuiltinTimeZoneGetInstantFor(timeZone, dateTime, disambiguation).
|
||||
...
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Try to create from the minimum date-time.
|
||||
{
|
||||
let dt = new Temporal.PlainDateTime(-271821, 4, 19, 0, 0, 0, 0, 0, 1);
|
||||
assert.throws(RangeError, () => dt.toZonedDateTime("UTC"));
|
||||
}
|
||||
{
|
||||
let dt = new Temporal.PlainDateTime(-271821, 4, 19, 1, 0, 0, 0, 0, 0);
|
||||
assert.throws(RangeError, () => dt.toZonedDateTime("UTC"));
|
||||
}
|
||||
|
||||
// Try to create from the maximum date-time.
|
||||
{
|
||||
let dt = new Temporal.PlainDateTime(275760, 9, 13, 0, 0, 0, 0, 0, 1);
|
||||
assert.throws(RangeError, () => dt.toZonedDateTime("UTC"));
|
||||
}
|
||||
{
|
||||
let dt = new Temporal.PlainDateTime(275760, 9, 13, 1, 0, 0, 0, 0, 0);
|
||||
assert.throws(RangeError, () => dt.toZonedDateTime("UTC"));
|
||||
}
|
45
test/built-ins/Temporal/PlainDateTime/prototype/until/balance-infinite-nanoseconds-duration.js
vendored
Normal file
45
test/built-ins/Temporal/PlainDateTime/prototype/until/balance-infinite-nanoseconds-duration.js
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaindatetime.prototype.since
|
||||
description: >
|
||||
BalanceDuration throws when the result duration is invalid.
|
||||
info: |
|
||||
DifferenceISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1,
|
||||
y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2,
|
||||
calendar, largestUnit, options )
|
||||
|
||||
...
|
||||
12. Let dateDifference be ? CalendarDateUntil(calendar, date1, date2, untilOptions).
|
||||
13. Let balanceResult be ? BalanceDuration(dateDifference.[[Days]], timeDifference.[[Hours]],
|
||||
timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]],
|
||||
timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]], largestUnit).
|
||||
...
|
||||
|
||||
BalanceDuration ( days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds,
|
||||
largestUnit [ , relativeTo ] )
|
||||
|
||||
...
|
||||
3. Else,
|
||||
a. Set nanoseconds to ! TotalDurationNanoseconds(days, hours, minutes, seconds, milliseconds,
|
||||
microseconds, nanoseconds, 0).
|
||||
...
|
||||
15. Return ? CreateTimeDurationRecord(days, hours × sign, minutes × sign, seconds × sign,
|
||||
milliseconds × sign, microseconds × sign, nanoseconds × sign).
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
var cal = new class extends Temporal.Calendar {
|
||||
dateUntil(date1, date2, options) {
|
||||
return Temporal.Duration.from({days: Number.MAX_VALUE});
|
||||
}
|
||||
}("iso8601");
|
||||
|
||||
var dt1 = new Temporal.PlainDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0, cal);
|
||||
var dt2 = new Temporal.PlainDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0, cal);
|
||||
var options = {largestUnit: "nanoseconds"};
|
||||
|
||||
assert.throws(RangeError, () => dt1.until(dt1, options));
|
||||
assert.throws(RangeError, () => dt1.until(dt2, options));
|
||||
assert.throws(RangeError, () => dt2.until(dt1, options));
|
18
test/built-ins/Temporal/PlainTime/prototype/add/argument-string-duration-too-large.js
vendored
Normal file
18
test/built-ins/Temporal/PlainTime/prototype/add/argument-string-duration-too-large.js
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaintime.prototype.add
|
||||
description: >
|
||||
ParseTemporalDurationString throws a RangeError when the result is too large.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Number string too long to be representable as a Number value.
|
||||
var ones = "1".repeat(1000);
|
||||
assert.sameValue(Number(ones), Infinity);
|
||||
|
||||
var time = new Temporal.PlainTime();
|
||||
var str = "PT" + ones + "S";
|
||||
|
||||
assert.throws(RangeError, () => time.add(str));
|
18
test/built-ins/Temporal/PlainTime/prototype/subtract/argument-string-duration-too-large.js
vendored
Normal file
18
test/built-ins/Temporal/PlainTime/prototype/subtract/argument-string-duration-too-large.js
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.plaintime.prototype.subtract
|
||||
description: >
|
||||
ParseTemporalDurationString throws a RangeError when the result is too large.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Number string too long to be representable as a Number value.
|
||||
var ones = "1".repeat(1000);
|
||||
assert.sameValue(Number(ones), Infinity);
|
||||
|
||||
var time = new Temporal.PlainTime();
|
||||
var str = "PT" + ones + "S";
|
||||
|
||||
assert.throws(RangeError, () => time.subtract(str));
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.timezone.prototype.getpossibleinstantsfor
|
||||
description: >
|
||||
Call getPossibleInstantsFor with values near the date/time limit and a fixed offset.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
const oneHour = 1n * 60n * 60n * 1000n**3n;
|
||||
|
||||
const minDt = new Temporal.PlainDateTime(-271821, 4, 19, 1, 0, 0, 0, 0, 0);
|
||||
const minValidDt = new Temporal.PlainDateTime(-271821, 4, 20, 0, 0, 0, 0, 0, 0);
|
||||
const maxDt = new Temporal.PlainDateTime(275760, 9, 13, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
let zero = new Temporal.TimeZone("+00");
|
||||
let plusOne = new Temporal.TimeZone("+01");
|
||||
let minusOne = new Temporal.TimeZone("-01");
|
||||
|
||||
// Try the minimum date-time.
|
||||
assert.throws(RangeError, () => zero.getPossibleInstantsFor(minDt));
|
||||
assert.throws(RangeError, () => plusOne.getPossibleInstantsFor(minDt));
|
||||
assert.throws(RangeError, () => minusOne.getPossibleInstantsFor(minDt));
|
||||
|
||||
// Try the minimum valid date-time.
|
||||
{
|
||||
let r = zero.getPossibleInstantsFor(minValidDt);
|
||||
assert.sameValue(r.length, 1);
|
||||
assert.sameValue(r[0].epochNanoseconds, -86_40000_00000_00000_00000n);
|
||||
}
|
||||
|
||||
{
|
||||
let r = minusOne.getPossibleInstantsFor(minValidDt);
|
||||
assert.sameValue(r.length, 1);
|
||||
assert.sameValue(r[0].epochNanoseconds, -86_40000_00000_00000_00000n + oneHour);
|
||||
}
|
||||
|
||||
assert.throws(RangeError, () => plusOne.getPossibleInstantsFor(minValidDt));
|
||||
|
||||
// Try the maximum valid date-time.
|
||||
{
|
||||
let r = zero.getPossibleInstantsFor(maxDt);
|
||||
assert.sameValue(r.length, 1);
|
||||
assert.sameValue(r[0].epochNanoseconds, 86_40000_00000_00000_00000n);
|
||||
}
|
||||
|
||||
{
|
||||
let r = plusOne.getPossibleInstantsFor(maxDt);
|
||||
assert.sameValue(r.length, 1);
|
||||
assert.sameValue(r[0].epochNanoseconds, 86_40000_00000_00000_00000n - oneHour);
|
||||
}
|
||||
|
||||
assert.throws(RangeError, () => minusOne.getPossibleInstantsFor(maxDt));
|
85
test/built-ins/Temporal/ZonedDateTime/prototype/round/smallest-unit-day-daylength-too-large.js
vendored
Normal file
85
test/built-ins/Temporal/ZonedDateTime/prototype/round/smallest-unit-day-daylength-too-large.js
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.zoneddatetime.prototype.round
|
||||
description: >
|
||||
Round smallestUnit "day" with very large or very small divisor (dayLengthNs).
|
||||
info: |
|
||||
Temporal.ZonedDateTime.prototype.round ( roundTo )
|
||||
...
|
||||
18. Let dayLengthNs be ℝ(endNs - startNs).
|
||||
...
|
||||
20. Let roundResult be ! RoundISODateTime(temporalDateTime.[[ISOYear]],
|
||||
temporalDateTime.[[ISOMonth]], temporalDateTime.[[ISODay]], temporalDateTime.[[ISOHour]],
|
||||
temporalDateTime.[[ISOMinute]], temporalDateTime.[[ISOSecond]],
|
||||
temporalDateTime.[[ISOMillisecond]], temporalDateTime.[[ISOMicrosecond]],
|
||||
temporalDateTime.[[ISONanosecond]], roundingIncrement, smallestUnit, roundingMode,
|
||||
dayLengthNs).
|
||||
...
|
||||
|
||||
RoundISODateTime ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond,
|
||||
increment, unit, roundingMode [ , dayLength ] )
|
||||
...
|
||||
4. Let roundedTime be ! RoundTime(hour, minute, second, millisecond, microsecond, nanosecond,
|
||||
increment, unit, roundingMode, dayLength).
|
||||
...
|
||||
|
||||
RoundTime ( hour, minute, second, millisecond, microsecond, nanosecond, increment, unit,
|
||||
roundingMode [ , dayLengthNs ] )
|
||||
...
|
||||
4. If unit is "day", then
|
||||
...
|
||||
b. Let quantity be (((((hour × 60 + minute) × 60 + second) × 1000 + millisecond) × 1000 +
|
||||
microsecond) × 1000 + nanosecond) / dayLengthNs.
|
||||
...
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
class TimeZone extends Temporal.TimeZone {
|
||||
#count = 0;
|
||||
#nanoseconds;
|
||||
|
||||
constructor(nanoseconds) {
|
||||
super("UTC");
|
||||
this.#nanoseconds = nanoseconds;
|
||||
}
|
||||
getPossibleInstantsFor(dateTime) {
|
||||
if (++this.#count === 2) {
|
||||
return [new Temporal.Instant(this.#nanoseconds)];
|
||||
}
|
||||
return super.getPossibleInstantsFor(dateTime);
|
||||
}
|
||||
}
|
||||
|
||||
const maxInstant = 86_40000_00000_00000_00000n;
|
||||
const minInstant = -86_40000_00000_00000_00000n;
|
||||
const oneDay = 24n * 60n * 60n * 1000n * 1000n * 1000n
|
||||
|
||||
// Divisor too large.
|
||||
{
|
||||
let tz = new TimeZone(maxInstant);
|
||||
let zoned = new Temporal.ZonedDateTime(0n, tz);
|
||||
let result = zoned.round({ smallestUnit: "days" });
|
||||
assert(zoned.equals(result));
|
||||
}
|
||||
{
|
||||
let tz = new TimeZone(maxInstant);
|
||||
let zoned = new Temporal.ZonedDateTime(minInstant, tz);
|
||||
let result = zoned.round({ smallestUnit: "days" });
|
||||
assert(zoned.equals(result));
|
||||
}
|
||||
|
||||
// Divisor too small.
|
||||
{
|
||||
let tz = new TimeZone(minInstant);
|
||||
let zoned = new Temporal.ZonedDateTime(0n, tz);
|
||||
let result = zoned.round({ smallestUnit: "days" });
|
||||
assert(zoned.equals(result));
|
||||
}
|
||||
{
|
||||
let tz = new TimeZone(minInstant);
|
||||
let zoned = new Temporal.ZonedDateTime(maxInstant - oneDay, tz);
|
||||
let result = zoned.round({ smallestUnit: "days" });
|
||||
assert(zoned.equals(result));
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.zoneddatetime.prototype.round
|
||||
description: >
|
||||
Round smallestUnit "day" with zero or negative day length.
|
||||
info: |
|
||||
Temporal.ZonedDateTime.prototype.round ( roundTo )
|
||||
...
|
||||
18. Let dayLengthNs be ℝ(endNs - startNs).
|
||||
19. If dayLengthNs is 0, then
|
||||
a. Throw a RangeError exception.
|
||||
20. Let roundResult be ! RoundISODateTime(temporalDateTime.[[ISOYear]],
|
||||
temporalDateTime.[[ISOMonth]], temporalDateTime.[[ISODay]], temporalDateTime.[[ISOHour]],
|
||||
temporalDateTime.[[ISOMinute]], temporalDateTime.[[ISOSecond]],
|
||||
temporalDateTime.[[ISOMillisecond]], temporalDateTime.[[ISOMicrosecond]],
|
||||
temporalDateTime.[[ISONanosecond]], roundingIncrement, smallestUnit, roundingMode,
|
||||
dayLengthNs).
|
||||
...
|
||||
|
||||
RoundISODateTime ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond,
|
||||
increment, unit, roundingMode [ , dayLength ] )
|
||||
...
|
||||
4. Let roundedTime be ! RoundTime(hour, minute, second, millisecond, microsecond, nanosecond,
|
||||
increment, unit, roundingMode, dayLength).
|
||||
...
|
||||
|
||||
RoundTime ( hour, minute, second, millisecond, microsecond, nanosecond, increment, unit,
|
||||
roundingMode [ , dayLengthNs ] )
|
||||
...
|
||||
4. If unit is "day", then
|
||||
...
|
||||
b. Let quantity be (((((hour × 60 + minute) × 60 + second) × 1000 + millisecond) × 1000 +
|
||||
microsecond) × 1000 + nanosecond) / dayLengthNs.
|
||||
...
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
class TimeZone extends Temporal.TimeZone {
|
||||
#count = 0;
|
||||
#nanoseconds;
|
||||
|
||||
constructor(nanoseconds) {
|
||||
super("UTC");
|
||||
this.#nanoseconds = nanoseconds;
|
||||
}
|
||||
getPossibleInstantsFor(dateTime) {
|
||||
if (++this.#count === 2) {
|
||||
return [new Temporal.Instant(this.#nanoseconds)];
|
||||
}
|
||||
return super.getPossibleInstantsFor(dateTime);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let tz = new TimeZone(0n);
|
||||
let zoned = new Temporal.ZonedDateTime(0n, tz);
|
||||
assert.throws(RangeError, () => zoned.round({ smallestUnit: "days" }));
|
||||
}
|
||||
|
||||
{
|
||||
let tz = new TimeZone(-1n);
|
||||
let zoned = new Temporal.ZonedDateTime(0n, tz);
|
||||
let result = zoned.round({ smallestUnit: "days" });
|
||||
assert(zoned.equals(result));
|
||||
}
|
30
test/built-ins/Temporal/ZonedDateTime/prototype/with/minimum-instant-with-one-hour-offset.js
vendored
Normal file
30
test/built-ins/Temporal/ZonedDateTime/prototype/with/minimum-instant-with-one-hour-offset.js
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.zoneddatetime.prototype.with
|
||||
description: >
|
||||
Throws a RangeError when ZonedDateTime at minimum instant and an explicit +1h offset.
|
||||
info: |
|
||||
Temporal.ZonedDateTime.prototype.with ( temporalZonedDateTimeLike [ , options ] )
|
||||
...
|
||||
21. Let epochNanoseconds be ? InterpretISODateTimeOffset(dateTimeResult.[[Year]],
|
||||
dateTimeResult.[[Month]], dateTimeResult.[[Day]], dateTimeResult.[[Hour]],
|
||||
dateTimeResult.[[Minute]], dateTimeResult.[[Second]], dateTimeResult.[[Millisecond]],
|
||||
dateTimeResult.[[Microsecond]], dateTimeResult.[[Nanosecond]], option, offsetNanoseconds,
|
||||
timeZone, disambiguation, offset, match exactly).
|
||||
...
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
let zdt = new Temporal.ZonedDateTime(-86_40000_00000_00000_00000n, "UTC");
|
||||
|
||||
let temporalZonedDateTimeLike = {
|
||||
offset: "+01",
|
||||
};
|
||||
|
||||
let options = {
|
||||
offset: "use",
|
||||
};
|
||||
|
||||
assert.throws(RangeError, () => zdt.with(temporalZonedDateTimeLike, options));
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.zoneddatetime.prototype.with
|
||||
description: >
|
||||
Throws a RangeError for the minimum date/value with UTC offset and an explicit offset.
|
||||
info: |
|
||||
Temporal.ZonedDateTime.prototype.with ( temporalZonedDateTimeLike [ , options ] )
|
||||
...
|
||||
21. Let epochNanoseconds be ? InterpretISODateTimeOffset(dateTimeResult.[[Year]],
|
||||
dateTimeResult.[[Month]], dateTimeResult.[[Day]], dateTimeResult.[[Hour]],
|
||||
dateTimeResult.[[Minute]], dateTimeResult.[[Second]], dateTimeResult.[[Millisecond]],
|
||||
dateTimeResult.[[Microsecond]], dateTimeResult.[[Nanosecond]], option, offsetNanoseconds,
|
||||
timeZone, disambiguation, offset, match exactly).
|
||||
...
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
let zdt = new Temporal.ZonedDateTime(0n, "UTC");
|
||||
|
||||
let temporalZonedDateTimeLike = {
|
||||
year: -271821,
|
||||
month: 4,
|
||||
day: 19,
|
||||
hour: 1,
|
||||
minute: 0,
|
||||
second: 0,
|
||||
millisecond: 0,
|
||||
microsecond: 0,
|
||||
nanosecond: 0,
|
||||
offset: "+00",
|
||||
};
|
||||
|
||||
let options = {
|
||||
offset: "use",
|
||||
};
|
||||
|
||||
assert.throws(RangeError, () => zdt.with(temporalZonedDateTimeLike, options));
|
34
test/built-ins/Temporal/ZonedDateTime/prototype/with/zoned-datetime-like-at-minimum-date-time.js
vendored
Normal file
34
test/built-ins/Temporal/ZonedDateTime/prototype/with/zoned-datetime-like-at-minimum-date-time.js
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.zoneddatetime.prototype.with
|
||||
description: >
|
||||
Throws a RangeError for the minimum date/value with UTC offset.
|
||||
info: |
|
||||
Temporal.ZonedDateTime.prototype.with ( temporalZonedDateTimeLike [ , options ] )
|
||||
...
|
||||
21. Let epochNanoseconds be ? InterpretISODateTimeOffset(dateTimeResult.[[Year]],
|
||||
dateTimeResult.[[Month]], dateTimeResult.[[Day]], dateTimeResult.[[Hour]],
|
||||
dateTimeResult.[[Minute]], dateTimeResult.[[Second]], dateTimeResult.[[Millisecond]],
|
||||
dateTimeResult.[[Microsecond]], dateTimeResult.[[Nanosecond]], option, offsetNanoseconds,
|
||||
timeZone, disambiguation, offset, match exactly).
|
||||
...
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
let zdt = new Temporal.ZonedDateTime(0n, "UTC");
|
||||
|
||||
let temporalZonedDateTimeLike = {
|
||||
year: -271821,
|
||||
month: 4,
|
||||
day: 19,
|
||||
hour: 1,
|
||||
minute: 0,
|
||||
second: 0,
|
||||
millisecond: 0,
|
||||
microsecond: 0,
|
||||
nanosecond: 0,
|
||||
};
|
||||
|
||||
assert.throws(RangeError, () => zdt.with(temporalZonedDateTimeLike));
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.timezone.prototype.getnexttransition
|
||||
description: >
|
||||
Compute next transition when seconds resp. nanoseconds are subtracted from the last transition.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// From <https://github.com/eggert/tz/blob/main/europe>:
|
||||
//
|
||||
// # Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
// Zone Europe/Paris 0:09:21 - LMT 1891 Mar 15 0:01
|
||||
// 0:09:21 - PMT 1911 Mar 11 0:01 # Paris MT
|
||||
|
||||
let tz = new Temporal.TimeZone("Europe/Paris");
|
||||
|
||||
let zdt = new Temporal.PlainDateTime(1800, 1, 1).toZonedDateTime(tz);
|
||||
assert.sameValue(zdt.toString(), "1800-01-01T00:00:00+00:09[Europe/Paris]");
|
||||
assert.sameValue(zdt.offsetNanoseconds, (9 * 60 + 21) * 1_000_000_000);
|
||||
|
||||
// Ensure the first transition was correctly computed.
|
||||
let first = tz.getNextTransition(zdt);
|
||||
assert.sameValue(first.toString(), "1911-03-10T23:50:39Z");
|
||||
assert.sameValue(new Temporal.ZonedDateTime(first.epochNanoseconds, tz).toString(),
|
||||
"1911-03-10T23:50:39+00:00[Europe/Paris]");
|
||||
|
||||
let next;
|
||||
|
||||
// Compute the next transition starting from the first transition minus 1s.
|
||||
let firstMinus1s = first.add({seconds: -1});
|
||||
assert.sameValue(firstMinus1s.toString(), "1911-03-10T23:50:38Z");
|
||||
assert.sameValue(new Temporal.ZonedDateTime(firstMinus1s.epochNanoseconds, tz).toString(),
|
||||
"1911-03-10T23:59:59+00:09[Europe/Paris]");
|
||||
assert.sameValue(new Temporal.ZonedDateTime(firstMinus1s.epochNanoseconds, tz).offsetNanoseconds,
|
||||
(9 * 60 + 21) * 1_000_000_000);
|
||||
|
||||
next = tz.getNextTransition(firstMinus1s);
|
||||
assert.sameValue(next.toString(), "1911-03-10T23:50:39Z");
|
||||
assert.sameValue(new Temporal.ZonedDateTime(next.epochNanoseconds, tz).toString(),
|
||||
"1911-03-10T23:50:39+00:00[Europe/Paris]");
|
||||
|
||||
// Compute the next transition starting from the first transition minus 1ns.
|
||||
let firstMinus1ns = first.add({nanoseconds: -1});
|
||||
assert.sameValue(firstMinus1ns.toString(), "1911-03-10T23:50:38.999999999Z");
|
||||
assert.sameValue(new Temporal.ZonedDateTime(firstMinus1ns.epochNanoseconds, tz).toString(),
|
||||
"1911-03-10T23:59:59.999999999+00:09[Europe/Paris]");
|
||||
assert.sameValue(new Temporal.ZonedDateTime(firstMinus1ns.epochNanoseconds, tz).offsetNanoseconds,
|
||||
(9 * 60 + 21) * 1_000_000_000);
|
||||
|
||||
next = tz.getNextTransition(firstMinus1ns);
|
||||
assert.sameValue(next.toString(), "1911-03-10T23:50:39Z");
|
||||
assert.sameValue(new Temporal.ZonedDateTime(next.epochNanoseconds, tz).toString(),
|
||||
"1911-03-10T23:50:39+00:00[Europe/Paris]");
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.timezone.prototype.getprevioustransition
|
||||
description: >
|
||||
Test previous transition when nanoseconds are subtracted resp. added to the DST transition.
|
||||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
let tz = new Temporal.TimeZone("Europe/Berlin");
|
||||
let p = Temporal.Instant.from("2021-03-28T01:00:00Z");
|
||||
|
||||
assert.sameValue(tz.getPreviousTransition(p.add({nanoseconds: -1})).toString(),
|
||||
"2020-10-25T01:00:00Z",
|
||||
"DST transition minus one nanosecond");
|
||||
|
||||
assert.sameValue(tz.getPreviousTransition(p).toString(),
|
||||
"2020-10-25T01:00:00Z",
|
||||
"DST transition");
|
||||
|
||||
assert.sameValue(tz.getPreviousTransition(p.add({nanoseconds: +1})).toString(),
|
||||
"2021-03-28T01:00:00Z",
|
||||
"DST transition plus one nanosecond");
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.timezone
|
||||
description: >
|
||||
TimeZone constructor accepts all time zone identifiers from Intl.supportedValuesOf.
|
||||
features: [Temporal, Intl-enumeration]
|
||||
---*/
|
||||
|
||||
// Ensure all identifiers are valid and canonical.
|
||||
for (let id of Intl.supportedValuesOf("timeZone")) {
|
||||
let tz = new Temporal.TimeZone(id);
|
||||
|
||||
assert.sameValue(tz.id, id);
|
||||
}
|
Loading…
Reference in New Issue