Skip to content

Commit d6a6c31

Browse files
authored
Merge branch 'main' into dasaria/await-dictionary-keyed-runtime-tests
2 parents 5e2c155 + e7c277b commit d6a6c31

File tree

24 files changed

+917
-382
lines changed

24 files changed

+917
-382
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (C) 2018 Bloomberg LP. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-datetime-format-functions
6+
description: datetime.toLocaleString()
7+
features: [Temporal]
8+
locale: [en-US]
9+
---*/
10+
11+
function maybeGetWeekdayOnlyFormat() {
12+
const fmt = new Intl.DateTimeFormat("en-US", { weekday: "long", timeZone: "+00:00" });
13+
const resolvedOptions = fmt.resolvedOptions();
14+
if (
15+
["era", "year", "month", "day", "hour", "minute", "second", "timeZoneName"].some(
16+
(prop) => prop in resolvedOptions
17+
)
18+
) {
19+
// no weekday-only format available
20+
return null;
21+
}
22+
return fmt;
23+
}
24+
25+
const fmt = maybeGetWeekdayOnlyFormat();
26+
if (fmt) {
27+
const expectedWeekday = fmt.format(new Date("1976-11-18T15:23:30"));
28+
29+
const datetime = Temporal.PlainDateTime.from("1976-11-18T15:23:30");
30+
assert.sameValue(fmt.format(datetime), expectedWeekday);
31+
32+
const date = Temporal.PlainDate.from("1976-11-18T15:23:30");
33+
assert.sameValue(fmt.format(date), expectedWeekday);
34+
35+
const instant = Temporal.Instant.from("1976-11-18T14:23:30Z");
36+
assert.sameValue(fmt.format(instant), expectedWeekday);
37+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright (C) 2026 André Bargull. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-partitiondatetimepattern
6+
description: >
7+
TimeClip is not applied for Temporal plain objects.
8+
info: |
9+
HandleDateTimeTemporalDate ( dateTimeFormat, temporalDate )
10+
...
11+
2. Let isoDateTime be CombineISODateAndTimeRecord(temporalDate.[[ISODate]], NoonTimeRecord()).
12+
3. Let epochNs be GetUTCEpochNanoseconds(isoDateTime).
13+
...
14+
6. Return Value Format Record { [[Format]]: format, [[EpochNanoseconds]]: epochNs, [[IsPlain]]: true }.
15+
16+
HandleDateTimeTemporalDateTime ( dateTimeFormat, dateTime )
17+
...
18+
2. Let epochNs be GetUTCEpochNanoseconds(dateTime.[[ISODateTime]]).
19+
...
20+
4. Return Value Format Record { [[Format]]: format, [[EpochNanoseconds]]: epochNs, [[IsPlain]]: true }.
21+
22+
HandleDateTimeTemporalYearMonth ( dateTimeFormat, temporalYearMonth )
23+
...
24+
2. Let isoDateTime be CombineISODateAndTimeRecord(temporalYearMonth.[[ISODate]], NoonTimeRecord()).
25+
3. Let epochNs be GetUTCEpochNanoseconds(isoDateTime).
26+
...
27+
6. Return Value Format Record { [[Format]]: format, [[EpochNanoseconds]]: epochNs, [[IsPlain]]: true }.
28+
29+
PartitionDateTimePattern ( dateTimeFormat, x )
30+
1. Let formatRecord be ? HandleDateTimeValue(dateTimeFormat, x).
31+
2. Let epochNanoseconds be formatRecord.[[EpochNanoseconds]].
32+
...
33+
6. Let result be FormatDateTimePattern(dateTimeFormat, format, pattern, epochNanoseconds, formatRecord.[[IsPlain]]).
34+
7. Return result.
35+
features: [Temporal]
36+
locale: [en]
37+
---*/
38+
39+
// Test with Temporal default calendar "iso8601" and additionally "gregory".
40+
var calendars = ["iso8601", "gregory"];
41+
42+
for (var calendar of calendars) {
43+
var dtf = new Intl.DateTimeFormat("en", {calendar});
44+
45+
// Minimum plain date value.
46+
var minDate = dtf.format(new Temporal.PlainDate(-271821, 4, 19, calendar));
47+
assert(minDate.includes("-271821") || minDate.includes("271822"), "minDate includes year");
48+
assert(minDate.includes("4"), "minDate includes month");
49+
assert(minDate.includes("19"), "minDate includes day");
50+
51+
// Maximum plain date value.
52+
var maxDate = dtf.format(new Temporal.PlainDate(275760, 9, 13, calendar));
53+
assert(maxDate.includes("275760"), "maxDate includes year");
54+
assert(maxDate.includes("9"), "maxDate includes month");
55+
assert(maxDate.includes("13"), "maxDate includes day");
56+
57+
// Minimum plain date-time value.
58+
var minDateTime = dtf.format(new Temporal.PlainDateTime(-271821, 4, 19, 0, 0, 0, 0, 0, 1, calendar));
59+
assert(minDateTime.includes("-271821") || minDate.includes("271822"), "minDateTime includes year");
60+
assert(minDateTime.includes("4"), "minDateTime includes month");
61+
assert(minDateTime.includes("19"), "minDateTime includes day");
62+
63+
// Maximum plain date-time value.
64+
var maxDateTime = dtf.format(new Temporal.PlainDateTime(275760, 9, 13, 23, 59, 59, 999, 999, 999, calendar));
65+
assert(maxDateTime.includes("275760"), "maxDateTime includes year");
66+
assert(maxDateTime.includes("9"), "maxDateTime includes month");
67+
assert(maxDateTime.includes("13"), "maxDateTime includes day");
68+
69+
// Minimum plain year-month value.
70+
var minYearMonth = dtf.format(new Temporal.PlainYearMonth(-271821, 4, calendar));
71+
assert(minYearMonth.includes("-271821") || minDate.includes("271822"), "minYearMonth includes year");
72+
assert(minYearMonth.includes("4"), "minYearMonth includes month");
73+
74+
// Maximum plain year-month value.
75+
var maxYearMonth = dtf.format(new Temporal.PlainYearMonth(275760, 9, calendar));
76+
assert(maxYearMonth.includes("275760"), "maxYearMonth includes year");
77+
assert(maxYearMonth.includes("9"), "maxYearMonth includes month");
78+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright (C) 2018 Bloomberg LP. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.instant.prototype.tolocalestring
6+
description: Basic tests for Temporal.Instant.toLocaleString
7+
info: |
8+
Temporal.Instant.prototype.toLocaleString ( [ locales [ , options ] ] )
9+
...
10+
4. Return ? FormatDateTime(dateFormat, instant).
11+
...
12+
13+
FormatDateTime ( dateTimeFormat, x )
14+
1. Let parts be ? PartitionDateTimePattern(dateTimeFormat, x).
15+
2. Let result be the empty String.
16+
3. For each Record { [[Type]], [[Value]] } part of parts, do
17+
a. Set result to the string-concatenation of result and part.[[Value]].
18+
4. Return result.
19+
20+
FormatDateTimeToParts ( dateTimeFormat, x )
21+
1. Let parts be ? PartitionDateTimePattern(dateTimeFormat, x).
22+
2. Let result be ! ArrayCreate(0).
23+
3. Let n be 0.
24+
4. For each Record { [[Type]], [[Value]] } part of parts, do
25+
a. Let O be OrdinaryObjectCreate(%Object.prototype%).
26+
b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).
27+
c. Perform ! CreateDataPropertyOrThrow(O, "value", part.[[Value]]).
28+
d. Perform ! CreateDataPropertyOrThrow(result, ! ToString(𝔽(n)), O).
29+
e. Increment n by 1.
30+
5. Return result.
31+
features: [Temporal]
32+
locale: [en-US, de-AT]
33+
---*/
34+
35+
function findPart(parts, expectedType) {
36+
return parts.find(({ type }) => type === expectedType).value;
37+
}
38+
39+
const instant = Temporal.Instant.from("1976-11-18T14:23:30Z");
40+
41+
const dtfNY = new Intl.DateTimeFormat("en-US", { timeZone: "America/New_York" });
42+
assert.sameValue(
43+
instant.toLocaleString("en-US", { timeZone: "America/New_York" }),
44+
dtfNY.format(instant)
45+
);
46+
47+
const partsNY = dtfNY.formatToParts(instant);
48+
const yearPartNY = findPart(partsNY, "year");
49+
const monthPartNY = findPart(partsNY, "month");
50+
const dayPartNY = findPart(partsNY, "day");
51+
const hourPartNY = findPart(partsNY, "hour");
52+
const minutePartNY = findPart(partsNY, "minute");
53+
const secondPartNY = findPart(partsNY, "second");
54+
const resultNY = instant.toLocaleString("en-US", { timeZone: "America/New_York" });
55+
assert(partsNY.some(part => part.type === "dayPeriod"), "en-US locale has a 12-hour format");
56+
assert(resultNY.includes(yearPartNY), "en-US locale string has a year part");
57+
assert(resultNY.includes(monthPartNY), "en-US locale string has a month part");
58+
assert(resultNY.includes(dayPartNY), "en-US locale string has a day part");
59+
assert(resultNY.includes(hourPartNY), "en-US locale string has an hour part");
60+
assert(resultNY.includes(minutePartNY), "en-US locale string has a minute part");
61+
assert(resultNY.includes(secondPartNY), "en-US locale string has a second part");
62+
63+
const dtfVienna = new Intl.DateTimeFormat("de-AT", { timeZone: "Europe/Vienna" });
64+
assert.sameValue(
65+
instant.toLocaleString("de-AT", { timeZone: "Europe/Vienna" }),
66+
dtfVienna.format(instant)
67+
);
68+
69+
const partsVienna = dtfVienna.formatToParts(instant);
70+
const yearPartVienna = findPart(partsVienna, "year");
71+
const monthPartVienna = findPart(partsVienna, "month");
72+
const dayPartVienna = findPart(partsVienna, "day");
73+
const hourPartVienna = findPart(partsVienna, "hour");
74+
const minutePartVienna = findPart(partsVienna, "minute");
75+
const secondPartVienna = findPart(partsVienna, "second");
76+
const resultVienna = instant.toLocaleString("de-AT", { timeZone: "Europe/Vienna" });
77+
assert(!partsVienna.some(part => part.type === "dayPeriod"), "de-AT locale has a 24-hour format");
78+
assert(resultVienna.includes(yearPartVienna), "de-AT locale string has a year part");
79+
assert(resultVienna.includes(monthPartVienna), "de-AT locale string has a month part");
80+
assert(resultVienna.includes(dayPartVienna), "de-AT locale string has a day part");
81+
assert(resultVienna.includes(hourPartVienna), "de-AT locale string has an hour part");
82+
assert(resultVienna.includes(minutePartVienna), "de-AT locale string has a minute part");
83+
assert(resultVienna.includes(secondPartVienna), "de-AT locale string has a second part");
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright (C) 2018 Bloomberg LP. 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.tolocalestring
6+
description: Instant.toLocaleString with option timeZoneName outputs a short name.
7+
features: [Temporal]
8+
locale: [en-US]
9+
---*/
10+
11+
const instant = Temporal.Instant.from("1976-11-18T14:23:30Z");
12+
const str = instant.toLocaleString("en-US", {
13+
timeZone: "America/New_York"
14+
});
15+
const strWithName = instant.toLocaleString("en-US", {
16+
timeZone: "America/New_York",
17+
timeZoneName: "short"
18+
});
19+
20+
assert(str.length < strWithName.length,
21+
'expected "' + str + '" to be shorter than "' + strWithName + '".');
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright (C) 2018 Bloomberg LP. 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.tolocalestring
6+
description: Basic tests for Temporal.PlainDate.toLocaleString
7+
info: |
8+
Temporal.PlainDate.prototype.toLocaleString ( [ locales [ , options ] ] )
9+
...
10+
4. Return ? FormatDateTime(dateFormat, plainDate).
11+
...
12+
13+
FormatDateTime ( dateTimeFormat, x )
14+
1. Let parts be ? PartitionDateTimePattern(dateTimeFormat, x).
15+
2. Let result be the empty String.
16+
3. For each Record { [[Type]], [[Value]] } part of parts, do
17+
a. Set result to the string-concatenation of result and part.[[Value]].
18+
4. Return result.
19+
20+
FormatDateTimeToParts ( dateTimeFormat, x )
21+
1. Let parts be ? PartitionDateTimePattern(dateTimeFormat, x).
22+
2. Let result be ! ArrayCreate(0).
23+
3. Let n be 0.
24+
4. For each Record { [[Type]], [[Value]] } part of parts, do
25+
a. Let O be OrdinaryObjectCreate(%Object.prototype%).
26+
b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).
27+
c. Perform ! CreateDataPropertyOrThrow(O, "value", part.[[Value]]).
28+
d. Perform ! CreateDataPropertyOrThrow(result, ! ToString(𝔽(n)), O).
29+
e. Increment n by 1.
30+
5. Return result.
31+
features: [Temporal]
32+
locale: [en-US, de-AT]
33+
---*/
34+
35+
function findPart(parts, expectedType) {
36+
return parts.find(({ type }) => type === expectedType).value;
37+
}
38+
39+
const date = Temporal.PlainDate.from("1976-11-18T15:23:30");
40+
41+
const dtfNY = new Intl.DateTimeFormat("en-US", { timeZone: "America/New_York" });
42+
assert.sameValue(
43+
date.toLocaleString("en-US", { timeZone: "America/New_York" }),
44+
dtfNY.format(date)
45+
);
46+
47+
const partsNY = dtfNY.formatToParts(date);
48+
const yearPartNY = findPart(partsNY, "year");
49+
const monthPartNY = findPart(partsNY, "month");
50+
const dayPartNY = findPart(partsNY, "day");
51+
const resultNY = date.toLocaleString("en-US", { timeZone: "America/New_York" });
52+
assert(resultNY.includes(yearPartNY), "en-US locale string has a year part");
53+
assert(resultNY.includes(monthPartNY), "en-US locale string has a month part");
54+
assert(resultNY.includes(dayPartNY), "en-US locale string has a day part");
55+
56+
const dtfVienna = new Intl.DateTimeFormat("de-AT", { timeZone: "Europe/Vienna" });
57+
assert.sameValue(
58+
date.toLocaleString("de-AT", { timeZone: "Europe/Vienna" }),
59+
dtfVienna.format(date)
60+
);
61+
62+
const partsVienna = dtfVienna.formatToParts(date);
63+
const yearPartVienna = findPart(partsVienna, "year");
64+
const monthPartVienna = findPart(partsVienna, "month");
65+
const dayPartVienna = findPart(partsVienna, "day");
66+
const resultVienna = date.toLocaleString("de-AT", { timeZone: "Europe/Vienna" });
67+
assert(resultVienna.includes(yearPartVienna), "de-AT locale string has a year part");
68+
assert(resultVienna.includes(monthPartVienna), "de-AT locale string has a month part");
69+
assert(resultVienna.includes(dayPartVienna), "de-AT locale string has a day part");
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright (C) 2018 Bloomberg LP. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.plaindatetime.prototype.tolocalestring
6+
description: Basic tests for Temporal.PlainDateTime.toLocaleString
7+
info: |
8+
Temporal.PlainDateTime.prototype.toLocaleString ( [ locales [ , options ] ] )
9+
...
10+
4. Return ? FormatDateTime(dateFormat, plainDateTime).
11+
...
12+
13+
FormatDateTime ( dateTimeFormat, x )
14+
1. Let parts be ? PartitionDateTimePattern(dateTimeFormat, x).
15+
2. Let result be the empty String.
16+
3. For each Record { [[Type]], [[Value]] } part of parts, do
17+
a. Set result to the string-concatenation of result and part.[[Value]].
18+
4. Return result.
19+
20+
FormatDateTimeToParts ( dateTimeFormat, x )
21+
1. Let parts be ? PartitionDateTimePattern(dateTimeFormat, x).
22+
2. Let result be ! ArrayCreate(0).
23+
3. Let n be 0.
24+
4. For each Record { [[Type]], [[Value]] } part of parts, do
25+
a. Let O be OrdinaryObjectCreate(%Object.prototype%).
26+
b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).
27+
c. Perform ! CreateDataPropertyOrThrow(O, "value", part.[[Value]]).
28+
d. Perform ! CreateDataPropertyOrThrow(result, ! ToString(𝔽(n)), O).
29+
e. Increment n by 1.
30+
5. Return result.
31+
features: [Temporal]
32+
locale: [en-US, de-AT]
33+
---*/
34+
35+
function findPart(parts, expectedType) {
36+
return parts.find(({ type }) => type === expectedType).value;
37+
}
38+
39+
const datetime = Temporal.PlainDateTime.from("1976-11-18T15:23:30");
40+
41+
const dtfNY = new Intl.DateTimeFormat("en-US", { timeZone: "America/New_York" });
42+
assert.sameValue(
43+
datetime.toLocaleString("en-US", { timeZone: "America/New_York" }),
44+
dtfNY.format(datetime)
45+
);
46+
47+
const partsNY = dtfNY.formatToParts(datetime);
48+
const yearPartNY = findPart(partsNY, "year");
49+
const monthPartNY = findPart(partsNY, "month");
50+
const dayPartNY = findPart(partsNY, "day");
51+
const hourPartNY = findPart(partsNY, "hour");
52+
const minutePartNY = findPart(partsNY, "minute");
53+
const secondPartNY = findPart(partsNY, "second");
54+
const resultNY = datetime.toLocaleString("en-US", { timeZone: "America/New_York" });
55+
assert(partsNY.some(part => part.type === "dayPeriod"), "en-US locale has a 12-hour format");
56+
assert(resultNY.includes(yearPartNY), "en-US locale string has a year part");
57+
assert(resultNY.includes(monthPartNY), "en-US locale string has a month part");
58+
assert(resultNY.includes(dayPartNY), "en-US locale string has a day part");
59+
assert(resultNY.includes(hourPartNY), "en-US locale string has an hour part");
60+
assert(resultNY.includes(minutePartNY), "en-US locale string has a minute part");
61+
assert(resultNY.includes(secondPartNY), "en-US locale string has a second part");
62+
63+
const dtfVienna = new Intl.DateTimeFormat("de-AT", { timeZone: "Europe/Vienna" });
64+
assert.sameValue(
65+
datetime.toLocaleString("de-AT", { timeZone: "Europe/Vienna" }),
66+
dtfVienna.format(datetime)
67+
);
68+
69+
const partsVienna = dtfVienna.formatToParts(datetime);
70+
const yearPartVienna = findPart(partsVienna, "year");
71+
const monthPartVienna = findPart(partsVienna, "month");
72+
const dayPartVienna = findPart(partsVienna, "day");
73+
const hourPartVienna = findPart(partsVienna, "hour");
74+
const minutePartVienna = findPart(partsVienna, "minute");
75+
const secondPartVienna = findPart(partsVienna, "second");
76+
const resultVienna = datetime.toLocaleString("de-AT", { timeZone: "Europe/Vienna" });
77+
assert(!partsVienna.some(part => part.type === "dayPeriod"), "de-AT locale has a 24-hour format");
78+
assert(resultVienna.includes(yearPartVienna), "de-AT locale string has a year part");
79+
assert(resultVienna.includes(monthPartVienna), "de-AT locale string has a month part");
80+
assert(resultVienna.includes(dayPartVienna), "de-AT locale string has a day part");
81+
assert(resultVienna.includes(hourPartVienna), "de-AT locale string has an hour part");
82+
assert(resultVienna.includes(minutePartVienna), "de-AT locale string has a minute part");
83+
assert(resultVienna.includes(secondPartVienna), "de-AT locale string has a second part");

0 commit comments

Comments
 (0)