Skip to content

Commit b98543d

Browse files
authored
Merge branch 'main' into webfeatures-map-iterator-updates
2 parents 688838b + a9af758 commit b98543d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2343
-72
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"private": true,
1414
"homepage": "https://github.com/tc39/test262#readme",
1515
"devDependencies": {
16-
"esvu": "^1.2.11",
16+
"esvu": "^1.3.0",
1717
"test262-harness": "^8.0.0"
1818
},
1919
"scripts": {

test/built-ins/Temporal/Instant/prototype/toString/timezone-string-datetime.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,20 @@ assert.throws(RangeError, () => instance.toString({ timeZone }), "bare date-time
4343

4444
timeZone = "2021-08-19T17:30Z";
4545
const result1 = instance.toString({ timeZone });
46-
assert.sameValue(result1.substr(-6), "+00:00", "date-time + Z is UTC time zone");
46+
assert.sameValue(result1.slice(-6), "+00:00", "date-time + Z is UTC time zone");
4747

4848
timeZone = "2021-08-19T17:30-07:00";
4949
const result2 = instance.toString({ timeZone });
50-
assert.sameValue(result2.substr(-6), "-07:00", "date-time + offset is the offset time zone");
50+
assert.sameValue(result2.slice(-6), "-07:00", "date-time + offset is the offset time zone");
5151

5252
timeZone = "2021-08-19T17:30[UTC]";
5353
const result3 = instance.toString({ timeZone });
54-
assert.sameValue(result3.substr(-6), "+00:00", "date-time + IANA annotation is the offset time zone");
54+
assert.sameValue(result3.slice(-6), "+00:00", "date-time + IANA annotation is the offset time zone");
5555

5656
timeZone = "2021-08-19T17:30Z[UTC]";
5757
const result4 = instance.toString({ timeZone });
58-
assert.sameValue(result4.substr(-6), "+00:00", "date-time + Z + IANA annotation is the offset time zone");
58+
assert.sameValue(result4.slice(-6), "+00:00", "date-time + Z + IANA annotation is the offset time zone");
5959

6060
timeZone = "2021-08-19T17:30-07:00[UTC]";
6161
const result5 = instance.toString({ timeZone });
62-
assert.sameValue(result5.substr(-6), "+00:00", "date-time + offset + IANA annotation is the offset time zone");
62+
assert.sameValue(result5.slice(-6), "+00:00", "date-time + offset + IANA annotation is the offset time zone");

test/built-ins/Temporal/Instant/prototype/toString/timezone-string-leap-second.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const instance = new Temporal.Instant(0n);
1111
let timeZone = "2016-12-31T23:59:60+00:00[UTC]";
1212

1313
const result = instance.toString({ timeZone });
14-
assert.sameValue(result.substr(-6), "+00:00", "leap second is a valid ISO string for TimeZone");
14+
assert.sameValue(result.slice(-6), "+00:00", "leap second is a valid ISO string for TimeZone");
1515

1616
timeZone = "2021-08-19T17:30:45.123456789+23:59[+23:59:60]";
1717
assert.throws(RangeError, () => instance.toString({ timeZone }), "leap second in time zone name not valid");

test/built-ins/Temporal/Instant/prototype/toString/timezone-string-multiple-offsets.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ const instance = new Temporal.Instant(0n);
1111
const timeZone = "2021-08-19T17:30:45.123456789-12:12[+01:46]";
1212

1313
const result = instance.toString({ timeZone });
14-
assert.sameValue(result.substr(-6), "+01:46", "Time zone string determined from bracket name");
14+
assert.sameValue(result.slice(-6), "+01:46", "Time zone string determined from bracket name");

test/built-ins/Temporal/Instant/prototype/toString/timezone-string.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ features: [Temporal]
1010
const instance = new Temporal.Instant(0n);
1111

1212
const result1 = instance.toString({ timeZone: "UTC" });
13-
assert.sameValue(result1.substr(-6), "+00:00", "Time zone created from string 'UTC'");
13+
assert.sameValue(result1.slice(-6), "+00:00", "Time zone created from string 'UTC'");
1414

1515
const result2 = instance.toString({ timeZone: "-01:30" });
16-
assert.sameValue(result2.substr(-6), "-01:30", "Time zone created from string '-01:30'");
16+
assert.sameValue(result2.slice(-6), "-01:30", "Time zone created from string '-01:30'");
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// Copyright (C) 2026 Rudolph Gottesheim. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.plaindate.prototype.since
6+
description: Half rounding modes at the exact 0.5 boundary for years and months
7+
info: |
8+
Tests that all rounding modes correctly break ties at the exact 0.5 boundary
9+
in RoundRelativeDuration in the negative direction, for both odd and even
10+
integer parts (distinguishing halfEven from other modes). In the negative
11+
direction, halfExpand and halfCeil diverge (away from zero vs toward positive
12+
infinity).
13+
14+
Years: dates 2019-01-01 / 2020-07-02 produce a difference of -1 year minus
15+
183 days. The year 2020 is a leap year (366 days), so fractional progress =
16+
183/366 = 0.5. Dates 2018-01-01 / 2020-07-02 produce -2 years minus 183 days
17+
(even integer part).
18+
19+
Months: dates 2019-01-01 / 2019-02-15 produce -1 month minus 14 days.
20+
February 2019 has 28 days, so fractional progress = 14/28 = 0.5.
21+
Dates 2018-12-01 / 2019-02-15 produce -2 months minus 14 days (even integer
22+
part).
23+
includes: [temporalHelpers.js]
24+
features: [Temporal]
25+
---*/
26+
27+
// --- years ---
28+
29+
// -1.5 years: odd integer part (1) + exact 0.5 fractional progress
30+
const yearEarlier1 = new Temporal.PlainDate(2019, 1, 1);
31+
const yearLater = new Temporal.PlainDate(2020, 7, 2);
32+
33+
assert.sameValue(
34+
yearEarlier1.until(yearLater).total({ unit: "years", relativeTo: yearEarlier1 }),
35+
1.5,
36+
"1.5-year duration is on a 0.5 boundary"
37+
);
38+
39+
for (const mode of ["trunc", "ceil", "halfTrunc", "halfCeil"]) {
40+
TemporalHelpers.assertDuration(
41+
yearEarlier1.since(yearLater, { smallestUnit: "years", roundingMode: mode }),
42+
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43+
`-1.5 years with ${mode} rounds toward zero`
44+
);
45+
}
46+
for (const mode of ["floor", "expand", "halfExpand", "halfFloor", "halfEven"]) {
47+
TemporalHelpers.assertDuration(
48+
yearEarlier1.since(yearLater, { smallestUnit: "years", roundingMode: mode }),
49+
-2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
50+
`-1.5 years with ${mode} rounds away from zero`
51+
);
52+
}
53+
54+
// -2.5 years: even integer part (2) — distinguishes halfEven from halfExpand
55+
const yearEarlier2 = new Temporal.PlainDate(2018, 1, 1);
56+
57+
assert.sameValue(
58+
yearEarlier2.until(yearLater).total({ unit: "years", relativeTo: yearEarlier2 }),
59+
2.5,
60+
"2.5-year duration is on a 0.5 boundary"
61+
);
62+
63+
for (const mode of ["trunc", "ceil", "halfTrunc", "halfCeil", "halfEven"]) {
64+
TemporalHelpers.assertDuration(
65+
yearEarlier2.since(yearLater, { smallestUnit: "years", roundingMode: mode }),
66+
-2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
67+
`-2.5 years with ${mode} rounds toward zero`
68+
);
69+
}
70+
for (const mode of ["floor", "expand", "halfExpand", "halfFloor"]) {
71+
TemporalHelpers.assertDuration(
72+
yearEarlier2.since(yearLater, { smallestUnit: "years", roundingMode: mode }),
73+
-3, 0, 0, 0, 0, 0, 0, 0, 0, 0,
74+
`-2.5 years with ${mode} rounds away from zero`
75+
);
76+
}
77+
78+
// --- months ---
79+
80+
// -1.5 months: odd integer part (1) + exact 0.5 fractional progress
81+
const monthEarlier1 = new Temporal.PlainDate(2019, 1, 1);
82+
const monthLater = new Temporal.PlainDate(2019, 2, 15);
83+
84+
assert.sameValue(
85+
monthEarlier1.until(monthLater).total({ unit: "months", relativeTo: monthEarlier1 }),
86+
1.5,
87+
"1.5-month duration is on a 0.5 boundary"
88+
);
89+
90+
for (const mode of ["trunc", "ceil", "halfTrunc", "halfCeil"]) {
91+
TemporalHelpers.assertDuration(
92+
monthEarlier1.since(monthLater, { smallestUnit: "months", roundingMode: mode }),
93+
0, -1, 0, 0, 0, 0, 0, 0, 0, 0,
94+
`-1.5 months with ${mode} rounds toward zero`
95+
);
96+
}
97+
for (const mode of ["floor", "expand", "halfExpand", "halfFloor", "halfEven"]) {
98+
TemporalHelpers.assertDuration(
99+
monthEarlier1.since(monthLater, { smallestUnit: "months", roundingMode: mode }),
100+
0, -2, 0, 0, 0, 0, 0, 0, 0, 0,
101+
`-1.5 months with ${mode} rounds away from zero`
102+
);
103+
}
104+
105+
// -2.5 months: even integer part (2) — distinguishes halfEven from halfExpand
106+
const monthEarlier2 = new Temporal.PlainDate(2018, 12, 1);
107+
108+
assert.sameValue(
109+
monthEarlier2.until(monthLater).total({ unit: "months", relativeTo: monthEarlier2 }),
110+
2.5,
111+
"2.5-month duration is on a 0.5 boundary"
112+
);
113+
114+
for (const mode of ["trunc", "ceil", "halfTrunc", "halfCeil", "halfEven"]) {
115+
TemporalHelpers.assertDuration(
116+
monthEarlier2.since(monthLater, { smallestUnit: "months", roundingMode: mode }),
117+
0, -2, 0, 0, 0, 0, 0, 0, 0, 0,
118+
`-2.5 months with ${mode} rounds toward zero`
119+
);
120+
}
121+
for (const mode of ["floor", "expand", "halfExpand", "halfFloor"]) {
122+
TemporalHelpers.assertDuration(
123+
monthEarlier2.since(monthLater, { smallestUnit: "months", roundingMode: mode }),
124+
0, -3, 0, 0, 0, 0, 0, 0, 0, 0,
125+
`-2.5 months with ${mode} rounds away from zero`
126+
);
127+
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// Copyright (C) 2026 Rudolph Gottesheim. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.plaindate.prototype.until
6+
description: Half rounding modes at the exact 0.5 boundary for years and months
7+
info: |
8+
Tests that all rounding modes correctly break ties at the exact 0.5 boundary
9+
in RoundRelativeDuration, for both odd and even integer parts (distinguishing
10+
halfEven from other modes).
11+
12+
Years: dates 2019-01-01 / 2020-07-02 produce 1 year + 183 days. The year
13+
2020 is a leap year (366 days), so fractional progress = 183/366 = 0.5.
14+
Dates 2018-01-01 / 2020-07-02 produce 2 years + 183 days (even integer part).
15+
16+
Months: dates 2019-01-01 / 2019-02-15 produce 1 month + 14 days. February
17+
2019 has 28 days, so fractional progress = 14/28 = 0.5. Dates 2018-12-01 /
18+
2019-02-15 produce 2 months + 14 days (even integer part).
19+
includes: [temporalHelpers.js]
20+
features: [Temporal]
21+
---*/
22+
23+
// --- years ---
24+
25+
// 1.5 years: odd integer part (1) + exact 0.5 fractional progress
26+
const yearEarlier1 = new Temporal.PlainDate(2019, 1, 1);
27+
const yearLater = new Temporal.PlainDate(2020, 7, 2);
28+
29+
assert.sameValue(
30+
yearEarlier1.until(yearLater).total({ unit: "years", relativeTo: yearEarlier1 }),
31+
1.5,
32+
"1.5-year duration is on a 0.5 boundary"
33+
);
34+
35+
for (const mode of ["trunc", "floor", "halfTrunc", "halfFloor"]) {
36+
TemporalHelpers.assertDuration(
37+
yearEarlier1.until(yearLater, { smallestUnit: "years", roundingMode: mode }),
38+
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39+
`1.5 years with ${mode} rounds down to 1`
40+
);
41+
}
42+
for (const mode of ["ceil", "expand", "halfExpand", "halfCeil", "halfEven"]) {
43+
TemporalHelpers.assertDuration(
44+
yearEarlier1.until(yearLater, { smallestUnit: "years", roundingMode: mode }),
45+
2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46+
`1.5 years with ${mode} rounds up to 2`
47+
);
48+
}
49+
50+
// 2.5 years: even integer part (2) — distinguishes halfEven from halfExpand
51+
const yearEarlier2 = new Temporal.PlainDate(2018, 1, 1);
52+
53+
assert.sameValue(
54+
yearEarlier2.until(yearLater).total({ unit: "years", relativeTo: yearEarlier2 }),
55+
2.5,
56+
"2.5-year duration is on a 0.5 boundary"
57+
);
58+
59+
for (const mode of ["trunc", "floor", "halfTrunc", "halfFloor", "halfEven"]) {
60+
TemporalHelpers.assertDuration(
61+
yearEarlier2.until(yearLater, { smallestUnit: "years", roundingMode: mode }),
62+
2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63+
`2.5 years with ${mode} rounds down to 2`
64+
);
65+
}
66+
for (const mode of ["ceil", "expand", "halfExpand", "halfCeil"]) {
67+
TemporalHelpers.assertDuration(
68+
yearEarlier2.until(yearLater, { smallestUnit: "years", roundingMode: mode }),
69+
3, 0, 0, 0, 0, 0, 0, 0, 0, 0,
70+
`2.5 years with ${mode} rounds up to 3`
71+
);
72+
}
73+
74+
// --- months ---
75+
76+
// 1.5 months: odd integer part (1) + exact 0.5 fractional progress
77+
const monthEarlier1 = new Temporal.PlainDate(2019, 1, 1);
78+
const monthLater = new Temporal.PlainDate(2019, 2, 15);
79+
80+
assert.sameValue(
81+
monthEarlier1.until(monthLater).total({ unit: "months", relativeTo: monthEarlier1 }),
82+
1.5,
83+
"1.5-month duration is on a 0.5 boundary"
84+
);
85+
86+
for (const mode of ["trunc", "floor", "halfTrunc", "halfFloor"]) {
87+
TemporalHelpers.assertDuration(
88+
monthEarlier1.until(monthLater, { smallestUnit: "months", roundingMode: mode }),
89+
0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
90+
`1.5 months with ${mode} rounds down to 1`
91+
);
92+
}
93+
for (const mode of ["ceil", "expand", "halfExpand", "halfCeil", "halfEven"]) {
94+
TemporalHelpers.assertDuration(
95+
monthEarlier1.until(monthLater, { smallestUnit: "months", roundingMode: mode }),
96+
0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
97+
`1.5 months with ${mode} rounds up to 2`
98+
);
99+
}
100+
101+
// 2.5 months: even integer part (2) — distinguishes halfEven from halfExpand
102+
const monthEarlier2 = new Temporal.PlainDate(2018, 12, 1);
103+
104+
assert.sameValue(
105+
monthEarlier2.until(monthLater).total({ unit: "months", relativeTo: monthEarlier2 }),
106+
2.5,
107+
"2.5-month duration is on a 0.5 boundary"
108+
);
109+
110+
for (const mode of ["trunc", "floor", "halfTrunc", "halfFloor", "halfEven"]) {
111+
TemporalHelpers.assertDuration(
112+
monthEarlier2.until(monthLater, { smallestUnit: "months", roundingMode: mode }),
113+
0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
114+
`2.5 months with ${mode} rounds down to 2`
115+
);
116+
}
117+
for (const mode of ["ceil", "expand", "halfExpand", "halfCeil"]) {
118+
TemporalHelpers.assertDuration(
119+
monthEarlier2.until(monthLater, { smallestUnit: "months", roundingMode: mode }),
120+
0, 3, 0, 0, 0, 0, 0, 0, 0, 0,
121+
`2.5 months with ${mode} rounds up to 3`
122+
);
123+
}

0 commit comments

Comments
 (0)