Temporal: Remove PlainTime.toPlainDateTime/toZonedDateTime methods

See tc39/proposal-temporal#2848
This commit is contained in:
Philip Chimento 2024-05-24 13:54:48 -07:00 committed by Philip Chimento
parent a9c223c60e
commit 7184313667
115 changed files with 0 additions and 3146 deletions

View File

@ -1,21 +0,0 @@
// 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.plaintime.prototype.toplaindatetime
description: >
Calling the method with a property bag argument with a builtin calendar causes
no observable array iteration when getting the calendar fields.
features: [Temporal]
---*/
const arrayPrototypeSymbolIteratorOriginal = Array.prototype[Symbol.iterator];
Array.prototype[Symbol.iterator] = function arrayIterator() {
throw new Test262Error("Array should not be iterated");
}
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const arg = { year: 2000, month: 5, day: 2, calendar: "iso8601" };
instance.toPlainDateTime(arg);
Array.prototype[Symbol.iterator] = arrayPrototypeSymbolIteratorOriginal;

View File

@ -1,16 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: >
Calendar.dateFromFields method is called with a null-prototype fields object
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const calendar = TemporalHelpers.calendarCheckFieldsPrototypePollution();
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const arg = { year: 2000, month: 5, day: 2, calendar };
instance.toPlainDateTime(arg);
assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");

View File

@ -1,14 +0,0 @@
// 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.plaintime.prototype.toplaindatetime
description: If a calendar's fields() method returns a field named 'constructor', PrepareTemporalFields should throw a RangeError.
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const calendar = TemporalHelpers.calendarWithExtraFields(['constructor']);
const arg = {year: 2023, month: 5, monthCode: 'M05', day: 1, calendar: calendar};
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
assert.throws(RangeError, () => instance.toPlainDateTime(arg));

View File

@ -1,16 +0,0 @@
// 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.plaintime.prototype.toplaindatetime
description: If a calendar's fields() method returns duplicate field names, PrepareTemporalFields should throw a RangeError.
includes: [temporalHelpers.js]
features: [Temporal]
---*/
for (const extra_fields of [['foo', 'foo'], ['day'], ['month'], ['monthCode'], ['year']]) {
const calendar = TemporalHelpers.calendarWithExtraFields(extra_fields);
const arg = { year: 2023, month: 5, monthCode: 'M05', day: 1, calendar: calendar };
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
assert.throws(RangeError, () => instance.toPlainDateTime(arg));
}

View File

@ -1,27 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: Leap second is a valid ISO string for PlainDate
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
let arg = "2016-12-31T23:59:60";
const result1 = instance.toPlainDateTime(arg);
TemporalHelpers.assertPlainDateTime(
result1,
2016, 12, "M12", 31, 12, 34, 56, 987, 654, 321,
"leap second is a valid ISO string for PlainDate"
);
arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 };
const result2 = instance.toPlainDateTime(arg);
TemporalHelpers.assertPlainDateTime(
result2,
2016, 12, "M12", 31, 12, 34, 56, 987, 654, 321,
"second: 60 is ignored in property bag for PlainDate"
);

View File

@ -1,25 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: A number cannot be used in place of a Temporal.PlainDate
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const numbers = [
1,
19761118,
-19761118,
1234567890,
];
for (const arg of numbers) {
assert.throws(
TypeError,
() => instance.toPlainDateTime(arg),
'Numbers cannot be used in place of an ISO string for PlainDate'
);
}

View File

@ -1,21 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.toplaindatetime
description: Fast path for converting Temporal.PlainDateTime to Temporal.PlainDate by reading internal slots
info: |
sec-temporal.plaintime.prototype.toplaindatetime step 3:
3. Set _temporalDate_ to ? ToTemporalDate(_temporalDate_).
sec-temporal-totemporaldate step 2.b:
b. If _item_ has an [[InitializedTemporalDateTime]] internal slot, then
i. Return ! CreateTemporalDate(_item_.[[ISOYear]], _item_.[[ISOMonth]], _item_.[[ISODay]], _item_.[[Calendar]]).
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
TemporalHelpers.checkPlainDateTimeConversionFastPath((datetime) => {
const time = new Temporal.PlainTime(6, 54, 32, 123, 456, 789);
const result = time.toPlainDateTime(datetime);
TemporalHelpers.assertPlainDateTime(result, 2000, 5, "M05", 2, 6, 54, 32, 123, 456, 789);
});

View File

@ -1,17 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: The calendar name is case-insensitive
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const calendar = "IsO8601";
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = instance.toPlainDateTime(arg);
TemporalHelpers.assertPlainDateTime(result, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, "Calendar is case-insensitive");

View File

@ -1,26 +0,0 @@
// Copyright (C) 2024 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: An ISO 8601 string can be converted to a calendar ID in Calendar
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
for (const calendar of [
"2020-01-01",
"2020-01-01[u-ca=iso8601]",
"2020-01-01T00:00:00.000000000",
"2020-01-01T00:00:00.000000000[u-ca=iso8601]",
"01-01",
"01-01[u-ca=iso8601]",
"2020-01",
"2020-01[u-ca=iso8601]",
]) {
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = instance.toPlainDateTime(arg);
TemporalHelpers.assertPlainDateTime(result, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, `Calendar created from string "${calendar}"`);
}

View File

@ -1,21 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: Leap second is a valid ISO string for a calendar in a property bag
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const calendar = "2016-12-31T23:59:60";
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = instance.toPlainDateTime(arg);
TemporalHelpers.assertPlainDateTime(
result,
1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321,
"leap second is a valid ISO string for calendar"
);

View File

@ -1,26 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: A number as calendar in a property bag is not accepted
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const numbers = [
1,
19970327,
-19970327,
1234567890,
];
for (const calendar of numbers) {
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
assert.throws(
TypeError,
() => instance.toPlainDateTime(arg),
"Numbers cannot be used as a calendar"
);
}

View File

@ -1,17 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: A calendar ID is valid input for Calendar
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const calendar = "iso8601";
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = instance.toPlainDateTime(arg);
TemporalHelpers.assertPlainDateTime(result, 1976, 11, "M11", 18, 12, 34, 56, 987, 654, 321, `Calendar created from string "${calendar}"`);

View File

@ -1,43 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: >
Appropriate error thrown when a calendar property from a property bag cannot
be converted to a calendar object or string
features: [BigInt, Symbol, Temporal]
---*/
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const primitiveTests = [
[null, "null"],
[true, "boolean"],
["", "empty string"],
[1, "number that doesn't convert to a valid ISO string"],
[1n, "bigint"],
];
for (const [calendar, description] of primitiveTests) {
const arg = { year: 2019, monthCode: "M11", day: 1, calendar };
assert.throws(
typeof calendar === 'string' ? RangeError : TypeError,
() => instance.toPlainDateTime(arg),
`${description} does not convert to a valid ISO string`
);
}
const typeErrorTests = [
[Symbol(), "symbol"],
[{}, "plain object that doesn't implement the protocol"],
[new Temporal.TimeZone("UTC"), "time zone instance"],
[Temporal.Calendar, "Temporal.Calendar, object"],
[Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
];
for (const [calendar, description] of typeErrorTests) {
const arg = { year: 2019, monthCode: "M11", day: 1, calendar };
assert.throws(TypeError, () => instance.toPlainDateTime(arg), `${description} is not a valid property bag and does not convert to a string`);
}

View File

@ -1,25 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: Negative zero, as an extended year, is rejected
features: [Temporal, arrow-function]
---*/
const invalidStrings = [
"-000000-10-31",
"-000000-10-31T17:45",
"-000000-10-31T17:45Z",
"-000000-10-31T17:45+01:00",
"-000000-10-31T17:45+00:00[UTC]",
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
invalidStrings.forEach((str) => {
const arg = { year: 1976, month: 11, day: 18, calendar: str };
assert.throws(
RangeError,
() => instance.toPlainDateTime(arg),
"reject minus zero as extended year"
);
});

View File

@ -1,14 +0,0 @@
// 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.plaintime.prototype.toplaindatetime
description: If a calendar's fields() method returns a field named '__proto__', PrepareTemporalFields should throw a RangeError.
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const calendar = TemporalHelpers.calendarWithExtraFields(['__proto__']);
const arg = {year: 2023, month: 5, monthCode: 'M05', day: 1, calendar: calendar};
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
assert.throws(RangeError, () => instance.toPlainDateTime(arg));

View File

@ -1,22 +0,0 @@
// Copyright (C) 2024 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: Annotation keys are lowercase-only
features: [Temporal]
---*/
const invalidStrings = [
["1970-01-01[U-CA=iso8601]", "invalid capitalized key"],
["1970-01-01[u-CA=iso8601]", "invalid partially-capitalized key"],
["1970-01-01[FOO=bar]", "invalid capitalized unrecognized key"],
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
invalidStrings.forEach(([arg, descr]) => {
assert.throws(
RangeError,
() => instance.toPlainDateTime(arg),
`annotation keys must be lowercase: ${arg} - ${descr}`
);
});

View File

@ -1,31 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: Various forms of calendar annotation; critical flag has no effect
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const tests = [
["2000-05-02[u-ca=iso8601]", "without time or time zone"],
["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"],
["2000-05-02T15:23[u-ca=iso8601]", "without time zone"],
["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"],
["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"],
["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"],
["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"],
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
tests.forEach(([arg, description]) => {
const result = instance.toPlainDateTime(arg);
TemporalHelpers.assertPlainDateTime(
result,
2000, 5, "M05", 2, 12, 34, 56, 987, 654, 321,
`calendar annotation (${description})`
);
});

View File

@ -1,25 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: Unknown annotations with critical flag are rejected
features: [Temporal]
---*/
const invalidStrings = [
"1970-01-01[!foo=bar]",
"1970-01-01T00:00[!foo=bar]",
"1970-01-01T00:00[UTC][!foo=bar]",
"1970-01-01T00:00[u-ca=iso8601][!foo=bar]",
"1970-01-01T00:00[UTC][!foo=bar][u-ca=iso8601]",
"1970-01-01T00:00[foo=bar][!_foo-bar0=Dont-Ignore-This-99999999999]",
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.toPlainDateTime(arg),
`reject unknown annotation with critical flag: ${arg}`
);
});

View File

@ -1,46 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: UTC offset not valid with format that does not include a time
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const validStrings = [
"2000-05-02T00+00:00",
"2000-05-02T00+00:00[UTC]",
"2000-05-02T00+00:00[!UTC]",
"2000-05-02T00-02:30[America/St_Johns]",
];
for (const arg of validStrings) {
const result = instance.toPlainDateTime(arg);
TemporalHelpers.assertPlainDateTime(
result,
2000, 5, "M05", 2, 12, 34, 56, 987, 654, 321,
`"${arg}" is a valid UTC offset with time for PlainDate`
);
}
const invalidStrings = [
"2022-09-15Z",
"2022-09-15Z[UTC]",
"2022-09-15Z[Europe/Vienna]",
"2022-09-15+00:00",
"2022-09-15+00:00[UTC]",
"2022-09-15-02:30",
"2022-09-15-02:30[America/St_Johns]",
];
for (const arg of invalidStrings) {
assert.throws(
RangeError,
() => instance.toPlainDateTime(arg),
`"${arg}" UTC offset without time is not valid for PlainDate`
);
}

View File

@ -1,61 +0,0 @@
// Copyright (C) 2022 Igalia S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: >
RangeError thrown if an invalid ISO string (or syntactically valid ISO string
that is not supported) is used as a PlainDate
features: [Temporal, arrow-function]
---*/
const invalidStrings = [
// invalid ISO strings:
"",
"invalid iso8601",
"2020-01-00",
"2020-01-32",
"2020-02-30",
"2021-02-29",
"2020-00-01",
"2020-13-01",
"2020-01-01T",
"2020-01-01T25:00:00",
"2020-01-01T01:60:00",
"2020-01-01T01:60:61",
"2020-01-01junk",
"2020-01-01T00:00:00junk",
"2020-01-01T00:00:00+00:00junk",
"2020-01-01T00:00:00+00:00[UTC]junk",
"2020-01-01T00:00:00+00:00[UTC][u-ca=iso8601]junk",
"02020-01-01",
"2020-001-01",
"2020-01-001",
"2020-01-01T001",
"2020-01-01T01:001",
"2020-01-01T01:01:001",
// valid, but forms not supported in Temporal:
"2020-W01-1",
"2020-001",
"+0002020-01-01",
// valid, but this calendar must not exist:
"2020-01-01[u-ca=notexist]",
// may be valid in other contexts, but insufficient information for PlainDate:
"2020-01",
"+002020-01",
"01-01",
"2020-W01",
"P1Y",
"-P12Y",
// valid, but outside the supported range:
"-999999-01-01",
"+999999-01-01",
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
for (const arg of invalidStrings) {
assert.throws(
RangeError,
() => instance.toPlainDateTime(arg),
`"${arg}" should not be a valid ISO string for a PlainDate`
);
}

View File

@ -1,29 +0,0 @@
// 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.plaintime.prototype.toplaindatetime
description: >
More than one calendar annotation is not syntactical if any have the criical
flag
features: [Temporal]
---*/
const invalidStrings = [
"1970-01-01[u-ca=iso8601][!u-ca=iso8601]",
"1970-01-01[!u-ca=iso8601][u-ca=iso8601]",
"1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]",
"1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]",
"1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]",
"1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]",
"1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]",
"1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]",
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.toPlainDateTime(arg),
`reject more than one calendar annotation if any critical: ${arg}`
);
});

View File

@ -1,25 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: More than one time zone annotation is not syntactical
features: [Temporal]
---*/
const invalidStrings = [
"1970-01-01[UTC][UTC]",
"1970-01-01T00:00[UTC][UTC]",
"1970-01-01T00:00[!UTC][UTC]",
"1970-01-01T00:00[UTC][!UTC]",
"1970-01-01T00:00[UTC][u-ca=iso8601][UTC]",
"1970-01-01T00:00[UTC][foo=bar][UTC]",
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.toPlainDateTime(arg),
`reject more than one time zone annotation: ${arg}`
);
});

View File

@ -1,27 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: Time separator in string argument can vary
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const tests = [
["2000-05-02T15:23", "uppercase T"],
["2000-05-02t15:23", "lowercase T"],
["2000-05-02 15:23", "space between date and time"],
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
tests.forEach(([arg, description]) => {
const result = instance.toPlainDateTime(arg);
TemporalHelpers.assertPlainDateTime(
result,
2000, 5, "M05", 2, 12, 34, 56, 987, 654, 321,
`variant time separators (${description})`
);
});

View File

@ -1,36 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: Various forms of time zone annotation; critical flag has no effect
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const tests = [
["2000-05-02[Asia/Kolkata]", "named, with no time"],
["2000-05-02[!Europe/Vienna]", "named, with ! and no time"],
["2000-05-02[+00:00]", "numeric, with no time"],
["2000-05-02[!-02:30]", "numeric, with ! and no time"],
["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"],
["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"],
["2000-05-02T15:23[-02:30]", "numeric, with no offset"],
["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"],
["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"],
["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"],
["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"],
["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"],
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
tests.forEach(([arg, description]) => {
const result = instance.toPlainDateTime(arg);
TemporalHelpers.assertPlainDateTime(
result,
2000, 5, "M05", 2, 12, 34, 56, 987, 654, 321,
`time zone annotation (${description})`
);
});

View File

@ -1,30 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: Various forms of unknown annotation
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const tests = [
["2000-05-02[foo=bar]", "without time"],
["2000-05-02T15:23[foo=bar]", "alone"],
["2000-05-02T15:23[UTC][foo=bar]", "with time zone"],
["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"],
["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"],
["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"],
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
tests.forEach(([arg, description]) => {
const result = instance.toPlainDateTime(arg);
TemporalHelpers.assertPlainDateTime(
result,
2000, 5, "M05", 2, 12, 34, 56, 987, 654, 321,
`unknown annotation (${description})`
);
});

View File

@ -1,21 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: RangeError thrown if a string with UTC designator is used as a PlainDate
features: [Temporal, arrow-function]
---*/
const invalidStrings = [
"2019-10-01T09:00:00Z",
"2019-10-01T09:00:00Z[UTC]",
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.toPlainDateTime(arg),
"String with UTC designator should not be valid as a PlainDate"
);
});

View File

@ -1,40 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: >
Appropriate error thrown when argument cannot be converted to a valid string
or property bag for PlainDate
features: [BigInt, Symbol, Temporal]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const primitiveTests = [
[undefined, "undefined"],
[null, "null"],
[true, "boolean"],
["", "empty string"],
[1, "number that doesn't convert to a valid ISO string"],
[1n, "bigint"],
];
for (const [arg, description] of primitiveTests) {
assert.throws(
typeof arg === 'string' ? RangeError : TypeError,
() => instance.toPlainDateTime(arg),
`${description} does not convert to a valid ISO string`
);
}
const typeErrorTests = [
[Symbol(), "symbol"],
[{}, "plain object"],
[Temporal.PlainDate, "Temporal.PlainDate, object"],
[Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"],
];
for (const [arg, description] of typeErrorTests) {
assert.throws(TypeError, () => instance.toPlainDateTime(arg), `${description} is not a valid property bag and does not convert to a string`);
}

View File

@ -1,19 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated.
features: [Temporal]
---*/
class TZ extends Temporal.TimeZone {
constructor() { super("UTC") }
getOffsetNanosecondsFor() { throw new Test262Error() }
}
const tz = new TZ();
const arg = new Temporal.ZonedDateTime(0n, tz);
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
assert.throws(Test262Error, () => instance.toPlainDateTime(arg));

View File

@ -1,37 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: Getters are not called when converting a ZonedDateTime to a PlainDate.
includes: [compareArray.js]
features: [Temporal]
---*/
const actual = [];
const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype);
const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"];
for (const property of getters) {
Object.defineProperty(Temporal.ZonedDateTime.prototype, property, {
get() {
actual.push(`get ${property}`);
const value = prototypeDescrs[property].get.call(this);
return {
toString() {
actual.push(`toString ${property}`);
return value.toString();
},
valueOf() {
actual.push(`valueOf ${property}`);
return value;
},
};
},
});
}
const arg = new Temporal.ZonedDateTime(0n, "UTC");
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
instance.toPlainDateTime(arg);
assert.compareArray(actual, []);

View File

@ -1,16 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: RangeError thrown if time zone reports an offset that is not an integer number of nanoseconds
features: [Temporal]
includes: [temporalHelpers.js]
---*/
[3600_000_000_000.5, NaN, -Infinity, Infinity].forEach((wrongOffset) => {
const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset);
const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
assert.throws(RangeError, () => time.toPlainDateTime(datetime));
});

View File

@ -1,20 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable
features: [BigInt, Symbol, Temporal, arrow-function]
---*/
[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach((notCallable) => {
const timeZone = new Temporal.TimeZone("UTC");
const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
timeZone.getOffsetNanosecondsFor = notCallable;
assert.throws(
TypeError,
() => time.toPlainDateTime(datetime),
`Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
);
});

View File

@ -1,16 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: RangeError thrown if time zone reports an offset that is out of range
features: [Temporal]
includes: [temporalHelpers.js]
---*/
[-86400_000_000_000, 86400_000_000_000].forEach((wrongOffset) => {
const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset);
const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
assert.throws(RangeError, () => time.toPlainDateTime(datetime));
});

View File

@ -1,25 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: TypeError thrown if time zone reports an offset that is not a Number
features: [Temporal]
includes: [temporalHelpers.js]
---*/
[
undefined,
null,
true,
"+01:00",
Symbol(),
3600_000_000_000n,
{},
{ valueOf() { return 3600_000_000_000; } },
].forEach((wrongOffset) => {
const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset);
const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
assert.throws(TypeError, () => time.toPlainDateTime(datetime));
});

View File

@ -1,22 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.toplaindatetime
description: Basic tests for toPlainDateTime().
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const plainTime = Temporal.PlainTime.from("11:30:23.123456789");
const plainDate = plainTime.toPlainDateTime(Temporal.PlainDate.from("1976-11-18"));
TemporalHelpers.assertPlainDateTime(plainDate, 1976, 11, "M11", 18, 11, 30, 23, 123, 456, 789, "PlainDate");
const optionBag = plainTime.toPlainDateTime({ year: 1976, month: 11, day: 18 });
TemporalHelpers.assertPlainDateTime(optionBag, 1976, 11, "M11", 18, 11, 30, 23, 123, 456, 789, "option bag");
const string = plainTime.toPlainDateTime("1976-11-18");
TemporalHelpers.assertPlainDateTime(string, 1976, 11, "M11", 18, 11, 30, 23, 123, 456, 789, "string");
assert.throws(TypeError, () => plainTime.toPlainDateTime({ year: 1976 }), "missing properties");

View File

@ -1,24 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: Throw a TypeError if the receiver is invalid
features: [Symbol, Temporal]
---*/
const toPlainDateTime = Temporal.PlainTime.prototype.toPlainDateTime;
assert.sameValue(typeof toPlainDateTime, "function");
const args = [new Temporal.PlainDate(2022, 6, 22)];
assert.throws(TypeError, () => toPlainDateTime.apply(undefined, args), "undefined");
assert.throws(TypeError, () => toPlainDateTime.apply(null, args), "null");
assert.throws(TypeError, () => toPlainDateTime.apply(true, args), "true");
assert.throws(TypeError, () => toPlainDateTime.apply("", args), "empty string");
assert.throws(TypeError, () => toPlainDateTime.apply(Symbol(), args), "symbol");
assert.throws(TypeError, () => toPlainDateTime.apply(1, args), "1");
assert.throws(TypeError, () => toPlainDateTime.apply({}, args), "plain object");
assert.throws(TypeError, () => toPlainDateTime.apply(Temporal.PlainTime, args), "Temporal.PlainTime");
assert.throws(TypeError, () => toPlainDateTime.apply(Temporal.PlainTime.prototype, args), "Temporal.PlainTime.prototype");

View File

@ -1,33 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: >
Tests that Temporal.PlainTime.prototype.toPlainDateTime
meets the requirements for built-in objects defined by the
introduction of chapter 17 of the ECMAScript Language Specification.
info: |
Built-in functions that are not constructors do not have a "prototype" property unless
otherwise specified in the description of a particular function.
Unless specified otherwise, a built-in object that is callable as a function is a built-in
function object with the characteristics described in 10.3. Unless specified otherwise, the
[[Extensible]] internal slot of a built-in object initially has the value true.
Unless otherwise specified every built-in function and every built-in constructor has the
Function prototype object [...] as the value of its [[Prototype]] internal slot.
features: [Temporal]
---*/
assert.sameValue(Object.isExtensible(Temporal.PlainTime.prototype.toPlainDateTime),
true, "Built-in objects must be extensible.");
assert.sameValue(Object.prototype.toString.call(Temporal.PlainTime.prototype.toPlainDateTime),
"[object Function]", "Object.prototype.toString");
assert.sameValue(Object.getPrototypeOf(Temporal.PlainTime.prototype.toPlainDateTime),
Function.prototype, "prototype");
assert.sameValue(Temporal.PlainTime.prototype.toPlainDateTime.hasOwnProperty("prototype"),
false, "prototype property");

View File

@ -1,16 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: >
Calendar.dateFromFields method is called with undefined as the options value
when call originates internally
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions();
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321, calendar);
instance.toPlainDateTime({ year: 2000, month: 5, day: 3, calendar });
assert.sameValue(calendar.dateFromFieldsCallCount, 1);

View File

@ -1,31 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: Verify the result of calendar.fields() is treated correctly.
info: |
sec-temporal.plaintime.prototype.toplaindatetime step 3:
3. Set _temporalDate_ to ? ToTemporalDate(_temporalDate_).
sec-temporal-totemporaldate step 2.c:
c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »).
sec-temporal-calendarfields step 4:
4. Let _result_ be ? IterableToList(_fieldsArray_).
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const expected = [
"day",
"month",
"monthCode",
"year",
];
const time = new Temporal.PlainTime(13, 3);
const calendar = TemporalHelpers.calendarFieldsIterable();
time.toPlainDateTime({ year: 2000, month: 5, day: 3, calendar });
assert.sameValue(calendar.fieldsCallCount, 1, "fields() method called once");
assert.compareArray(calendar.fieldsCalledWith[0], expected, "fields() method called with correct args");
assert(calendar.iteratorExhausted[0], "iterated through the whole iterable");

View File

@ -1,27 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
info: |
sec-temporal.plaintime.prototype.toplaindatetime step 3:
3. Set _temporalDate_ to ? ToTemporalDate(_temporalDate_).
sec-temporal-totemporaldate step 2.c:
c. Let _calendar_ be ? GetTemporalCalendarWithISODefault(_item_).
sec-temporal-gettemporalcalendarwithisodefault step 2:
2. Return ? ToTemporalCalendarWithISODefault(_calendar_).
sec-temporal-totemporalcalendarwithisodefault step 2:
3. Return ? ToTemporalCalendar(_temporalCalendarLike_).
sec-temporal-totemporalcalendar step 1.a:
a. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then
i. Return _temporalCalendarLike_.[[Calendar]].
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject, calendar) => {
const time = new Temporal.PlainTime(13, 3);
const result = time.toPlainDateTime({ year: 2000, month: 5, day: 3, calendar: temporalObject });
assert.sameValue(result.getCalendar(), calendar, "Temporal object coerced to calendar");
});

View File

@ -1,23 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Throws if any value in the property bag is Infinity or -Infinity
esid: sec-temporal.plaintime.prototype.toplaindatetime
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(15);
const base = { year: 2000, month: 5, day: 2 };
[Infinity, -Infinity].forEach((inf) => {
["year", "month", "day"].forEach((prop) => {
assert.throws(RangeError, () => instance.toPlainDateTime({ ...base, [prop]: inf }), `${prop} property cannot be ${inf}`);
const calls = [];
const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
assert.throws(RangeError, () => instance.toPlainDateTime({ ...base, [prop]: obj }));
assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
});
});

View File

@ -1,25 +0,0 @@
// Copyright (C) 2020 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: Temporal.PlainTime.prototype.toPlainDateTime.length is 1
info: |
Every built-in function object, including constructors, has a "length" property whose value is
an integer. Unless otherwise specified, this value is equal to the largest number of named
arguments shown in the subclause headings for the function description. Optional parameters
(which are indicated with brackets: [ ]) or rest parameters (which are shown using the form
«...name») are not included in the default argument count.
Unless otherwise specified, the "length" property of a built-in function object has the
attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
includes: [propertyHelper.js]
features: [Temporal]
---*/
verifyProperty(Temporal.PlainTime.prototype.toPlainDateTime, "length", {
value: 1,
writable: false,
enumerable: false,
configurable: true,
});

View File

@ -1,39 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: Checking limits of representable PlainDateTime
features: [Temporal]
includes: [temporalHelpers.js]
---*/
const midnight = new Temporal.PlainTime(0, 0);
const firstNs = new Temporal.PlainTime(0, 0, 0, 0, 0, 1);
const lastNs = new Temporal.PlainTime(23, 59, 59, 999, 999, 999);
const min = new Temporal.PlainDate(-271821, 4, 19);
const max = new Temporal.PlainDate(275760, 9, 13);
assert.throws(
RangeError,
() => midnight.toPlainDateTime(min),
"Cannot go below representable limit"
);
TemporalHelpers.assertPlainDateTime(
midnight.toPlainDateTime(max),
275760, 9, "M09", 13, 0, 0, 0, 0, 0, 0,
"Midnight of maximum representable PlainDate"
);
TemporalHelpers.assertPlainDateTime(
firstNs.toPlainDateTime(min),
-271821, 4, "M04", 19, 0, 0, 0, 0, 0, 1,
"Computing the minimum (earliest) representable PlainDateTime"
);
TemporalHelpers.assertPlainDateTime(
lastNs.toPlainDateTime(max),
275760, 9, "M09", 13, 23, 59, 59, 999, 999, 999,
"Computing the maximum (latest) representable PlainDateTime"
);

View File

@ -1,23 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: Temporal.PlainTime.prototype.toPlainDateTime.name is "toPlainDateTime".
info: |
Every built-in function object, including constructors, that is not identified as an anonymous
function has a "name" property whose value is a String. Unless otherwise specified, this value
is the name that is given to the function in this specification.
Unless otherwise specified, the "name" property of a built-in function object, if it exists,
has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
includes: [propertyHelper.js]
features: [Temporal]
---*/
verifyProperty(Temporal.PlainTime.prototype.toPlainDateTime, "name", {
value: "toPlainDateTime",
writable: false,
enumerable: false,
configurable: true,
});

View File

@ -1,21 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: >
Temporal.PlainTime.prototype.toPlainDateTime does not implement [[Construct]], is not new-able
info: |
Built-in function objects that are not identified as constructors do not implement the
[[Construct]] internal method unless otherwise specified in the description of a particular
function.
includes: [isConstructor.js]
features: [Reflect.construct, Temporal]
---*/
assert.throws(TypeError, () => {
new Temporal.PlainTime.prototype.toPlainDateTime();
}, "Calling as constructor");
assert.sameValue(isConstructor(Temporal.PlainTime.prototype.toPlainDateTime), false,
"isConstructor(Temporal.PlainTime.prototype.toPlainDateTime)");

View File

@ -1,21 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: The "toPlainDateTime" property of Temporal.PlainTime.prototype
includes: [propertyHelper.js]
features: [Temporal]
---*/
assert.sameValue(
typeof Temporal.PlainTime.prototype.toPlainDateTime,
"function",
"`typeof PlainTime.prototype.toPlainDateTime` is `function`"
);
verifyProperty(Temporal.PlainTime.prototype, "toPlainDateTime", {
writable: true,
enumerable: false,
configurable: true,
});

View File

@ -1,23 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.toplaindatetime
description: Negative zero, as an extended year, is rejected
features: [Temporal, arrow-function]
---*/
const invalidStrings = [
"-000000-10-31",
"-000000-10-31T00:45",
"-000000-10-31T00:45+01:00",
"-000000-10-31T00:45+00:00[UTC]",
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.toPlainDateTime(arg),
"reject minus zero as extended year"
);
});

View File

@ -1,21 +0,0 @@
// 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.plaintime.prototype.tozoneddatetime
description: >
Calling the method with a property bag argument with a builtin calendar causes
no observable array iteration when getting the calendar fields.
features: [Temporal]
---*/
const arrayPrototypeSymbolIteratorOriginal = Array.prototype[Symbol.iterator];
Array.prototype[Symbol.iterator] = function arrayIterator() {
throw new Test262Error("Array should not be iterated");
}
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const arg = { year: 2000, month: 5, day: 2, calendar: "iso8601" };
instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" });
Array.prototype[Symbol.iterator] = arrayPrototypeSymbolIteratorOriginal;

View File

@ -1,16 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: >
Calendar.dateFromFields method is called with a null-prototype fields object
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const calendar = TemporalHelpers.calendarCheckFieldsPrototypePollution();
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const arg = { year: 2000, month: 5, day: 2, calendar };
instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" });
assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");

View File

@ -1,14 +0,0 @@
// 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.plaintime.prototype.tozoneddatetime
description: If a calendar's fields() method returns a field named 'constructor', PrepareTemporalFields should throw a RangeError.
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const calendar = TemporalHelpers.calendarWithExtraFields(['constructor']);
const arg = {year: 2023, month: 5, monthCode: 'M05', day: 1, calendar: calendar};
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }));

View File

@ -1,16 +0,0 @@
// 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.plaintime.prototype.tozoneddatetime
description: If a calendar's fields() method returns duplicate field names, PrepareTemporalFields should throw a RangeError.
includes: [temporalHelpers.js]
features: [Temporal]
---*/
for (const extra_fields of [['foo', 'foo'], ['day'], ['month'], ['monthCode'], ['year']]) {
const calendar = TemporalHelpers.calendarWithExtraFields(extra_fields);
const arg = { year: 2023, month: 5, monthCode: 'M05', day: 1, calendar: calendar };
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }));
}

View File

@ -1,26 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: Leap second is a valid ISO string for PlainDate
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
let arg = "2016-12-31T23:59:60";
const result1 = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" });
assert.sameValue(
result1.epochNanoseconds,
1_483_187_696_987_654_321n,
"leap second is a valid ISO string for PlainDate"
);
arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 };
const result2 = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" });
assert.sameValue(
result2.epochNanoseconds,
1_483_187_696_987_654_321n,
"second: 60 is ignored in property bag for PlainDate"
);

View File

@ -1,25 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: A number cannot be used in place of a Temporal.PlainDate
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const numbers = [
1,
19761118,
-19761118,
1234567890,
];
for (const arg of numbers) {
assert.throws(
TypeError,
() => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }),
'Numbers cannot be used in place of an ISO string for PlainDate'
);
}

View File

@ -1,29 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.tozoneddatetime
description: Fast path for converting Temporal.PlainDateTime to Temporal.PlainDate by reading internal slots
info: |
sec-temporal.plaintime.prototype.tozoneddatetime step 5:
5. Let _temporalDate_ be ? ToTemporalDate(_temporalDateLike_).
sec-temporal-totemporaldate step 2.b:
b. If _item_ has an [[InitializedTemporalDateTime]] internal slot, then
i. Return ! CreateTemporalDate(_item_.[[ISOYear]], _item_.[[ISOMonth]], _item_.[[ISODay]], _item_.[[Calendar]]).
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
TemporalHelpers.checkPlainDateTimeConversionFastPath((datetime) => {
const time = new Temporal.PlainTime(6, 54, 32, 123, 456, 789);
const result = time.toZonedDateTime({ plainDate: datetime, timeZone: "UTC" });
assert.sameValue(result.year, 2000, "year result");
assert.sameValue(result.month, 5, "month result");
assert.sameValue(result.day, 2, "day result");
assert.sameValue(result.hour, 6, "hour result");
assert.sameValue(result.minute, 54, "minute result");
assert.sameValue(result.second, 32, "second result");
assert.sameValue(result.millisecond, 123, "millisecond result");
assert.sameValue(result.microsecond, 456, "microsecond result");
assert.sameValue(result.nanosecond, 789, "nanosecond result");
});

View File

@ -1,23 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.tozoneddatetime
description: TypeError thrown if a primitive is passed as the argument
info: |
Temporal.PlainTime.prototype.toZonedDateTime ( item )
3. If Type(item) is not Object, then
a. Throw a TypeError exception.
features: [Symbol, Temporal]
---*/
const instance = Temporal.PlainTime.from("00:00");
assert.throws(TypeError, () => instance.toZonedDateTime(undefined), "undefined");
assert.throws(TypeError, () => instance.toZonedDateTime(null), "null");
assert.throws(TypeError, () => instance.toZonedDateTime(true), "true");
assert.throws(TypeError, () => instance.toZonedDateTime(""), "empty string");
assert.throws(TypeError, () => instance.toZonedDateTime(Symbol()), "symbol");
assert.throws(TypeError, () => instance.toZonedDateTime(1), "1");
assert.throws(TypeError, () => instance.toZonedDateTime(1n), "1n");

View File

@ -1,16 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: The calendar name is case-insensitive
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const calendar = "IsO8601";
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" });
assert.sameValue(result.epochNanoseconds, 217_168_496_987_654_321n, "Calendar is case-insensitive");

View File

@ -1,25 +0,0 @@
// Copyright (C) 2024 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: An ISO 8601 string can be converted to a calendar ID in Calendar
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
for (const calendar of [
"2020-01-01",
"2020-01-01[u-ca=iso8601]",
"2020-01-01T00:00:00.000000000",
"2020-01-01T00:00:00.000000000[u-ca=iso8601]",
"01-01",
"01-01[u-ca=iso8601]",
"2020-01",
"2020-01[u-ca=iso8601]",
]) {
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" });
assert.sameValue(result.epochNanoseconds, 217_168_496_987_654_321n, `Calendar created from string "${calendar}"`);
}

View File

@ -1,20 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: Leap second is a valid ISO string for a calendar in a property bag
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const calendar = "2016-12-31T23:59:60";
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" });
assert.sameValue(
result.epochNanoseconds,
217_168_496_987_654_321n,
"leap second is a valid ISO string for calendar"
);

View File

@ -1,26 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: A number as calendar in a property bag is not accepted
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const numbers = [
1,
19970327,
-19970327,
1234567890,
];
for (const calendar of numbers) {
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
assert.throws(
TypeError,
() => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }),
"Numbers cannot be used as a calendar"
);
}

View File

@ -1,16 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: A calendar ID is valid input for Calendar
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const calendar = "iso8601";
const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" });
assert.sameValue(result.epochNanoseconds, 217_168_496_987_654_321n, `Calendar created from string "${calendar}"`);

View File

@ -1,43 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: >
Appropriate error thrown when a calendar property from a property bag cannot
be converted to a calendar object or string
features: [BigInt, Symbol, Temporal]
---*/
const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const primitiveTests = [
[null, "null"],
[true, "boolean"],
["", "empty string"],
[1, "number that doesn't convert to a valid ISO string"],
[1n, "bigint"],
];
for (const [calendar, description] of primitiveTests) {
const arg = { year: 2019, monthCode: "M11", day: 1, calendar };
assert.throws(
typeof calendar === 'string' ? RangeError : TypeError,
() => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }),
`${description} does not convert to a valid ISO string`
);
}
const typeErrorTests = [
[Symbol(), "symbol"],
[{}, "plain object that doesn't implement the protocol"],
[new Temporal.TimeZone("UTC"), "time zone instance"],
[Temporal.Calendar, "Temporal.Calendar, object"],
[Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
];
for (const [calendar, description] of typeErrorTests) {
const arg = { year: 2019, monthCode: "M11", day: 1, calendar };
assert.throws(TypeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), `${description} is not a valid property bag and does not convert to a string`);
}

View File

@ -1,25 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: Negative zero, as an extended year, is rejected
features: [Temporal, arrow-function]
---*/
const invalidStrings = [
"-000000-10-31",
"-000000-10-31T17:45",
"-000000-10-31T17:45Z",
"-000000-10-31T17:45+01:00",
"-000000-10-31T17:45+00:00[UTC]",
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
invalidStrings.forEach((str) => {
const arg = { year: 1976, month: 11, day: 18, calendar: str };
assert.throws(
RangeError,
() => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }),
"reject minus zero as extended year"
);
});

View File

@ -1,22 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.tozoneddatetime
description: Both plainDate and timeZone properties need to not be undefined.
features: [Temporal]
---*/
const instance = new Temporal.PlainTime();
const plainDate = new Temporal.PlainDate(2022, 5, 19);
const timeZone = new Temporal.TimeZone("UTC");
assert.throws(TypeError, () => instance.toZonedDateTime({}),
"no properties");
assert.throws(TypeError, () => instance.toZonedDateTime({ plainDate }),
"only plainDate");
assert.throws(TypeError, () => instance.toZonedDateTime({ plainDate, timeZone: undefined }),
"timeZone explicitly undefined");
assert.throws(TypeError, () => instance.toZonedDateTime({ timeZone }),
"only timeZone");
assert.throws(TypeError, () => instance.toZonedDateTime({ plainDate: undefined, timeZone }),
"plainDate explicitly undefined");

View File

@ -1,14 +0,0 @@
// 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.plaintime.prototype.tozoneddatetime
description: If a calendar's fields() method returns a field named '__proto__', PrepareTemporalFields should throw a RangeError.
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const calendar = TemporalHelpers.calendarWithExtraFields(['__proto__']);
const arg = {year: 2023, month: 5, monthCode: 'M05', day: 1, calendar: calendar};
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
assert.throws(RangeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }));

View File

@ -1,22 +0,0 @@
// Copyright (C) 2024 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: Annotation keys are lowercase-only
features: [Temporal]
---*/
const invalidStrings = [
["1970-01-01[U-CA=iso8601]", "invalid capitalized key"],
["1970-01-01[u-CA=iso8601]", "invalid partially-capitalized key"],
["1970-01-01[FOO=bar]", "invalid capitalized unrecognized key"],
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
invalidStrings.forEach(([arg, descr]) => {
assert.throws(
RangeError,
() => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }),
`annotation keys must be lowercase: ${arg} - ${descr}`
);
});

View File

@ -1,30 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: Various forms of calendar annotation; critical flag has no effect
features: [Temporal]
---*/
const tests = [
["2000-05-02[u-ca=iso8601]", "without time or time zone"],
["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"],
["2000-05-02T15:23[u-ca=iso8601]", "without time zone"],
["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"],
["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"],
["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"],
["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"],
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
tests.forEach(([arg, description]) => {
const result = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" });
assert.sameValue(
result.epochNanoseconds,
957_270_896_987_654_321n,
`calendar annotation (${description})`
);
});

View File

@ -1,25 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: Unknown annotations with critical flag are rejected
features: [Temporal]
---*/
const invalidStrings = [
"1970-01-01[!foo=bar]",
"1970-01-01T00:00[!foo=bar]",
"1970-01-01T00:00[UTC][!foo=bar]",
"1970-01-01T00:00[u-ca=iso8601][!foo=bar]",
"1970-01-01T00:00[UTC][!foo=bar][u-ca=iso8601]",
"1970-01-01T00:00[foo=bar][!_foo-bar0=Dont-Ignore-This-99999999999]",
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }),
`reject unknown annotation with critical flag: ${arg}`
);
});

View File

@ -1,45 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: UTC offset not valid with format that does not include a time
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const validStrings = [
"2000-05-02T00+00:00",
"2000-05-02T00+00:00[UTC]",
"2000-05-02T00+00:00[!UTC]",
"2000-05-02T00-02:30[America/St_Johns]",
];
for (const arg of validStrings) {
const result = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" });
assert.sameValue(
result.epochNanoseconds,
957_270_896_987_654_321n,
`"${arg}" is a valid UTC offset with time for PlainDate`
);
}
const invalidStrings = [
"2022-09-15Z",
"2022-09-15Z[UTC]",
"2022-09-15Z[Europe/Vienna]",
"2022-09-15+00:00",
"2022-09-15+00:00[UTC]",
"2022-09-15-02:30",
"2022-09-15-02:30[America/St_Johns]",
];
for (const arg of invalidStrings) {
assert.throws(
RangeError,
() => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }),
`"${arg}" UTC offset without time is not valid for PlainDate`
);
}

View File

@ -1,61 +0,0 @@
// Copyright (C) 2022 Igalia S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: >
RangeError thrown if an invalid ISO string (or syntactically valid ISO string
that is not supported) is used as a PlainDate
features: [Temporal, arrow-function]
---*/
const invalidStrings = [
// invalid ISO strings:
"",
"invalid iso8601",
"2020-01-00",
"2020-01-32",
"2020-02-30",
"2021-02-29",
"2020-00-01",
"2020-13-01",
"2020-01-01T",
"2020-01-01T25:00:00",
"2020-01-01T01:60:00",
"2020-01-01T01:60:61",
"2020-01-01junk",
"2020-01-01T00:00:00junk",
"2020-01-01T00:00:00+00:00junk",
"2020-01-01T00:00:00+00:00[UTC]junk",
"2020-01-01T00:00:00+00:00[UTC][u-ca=iso8601]junk",
"02020-01-01",
"2020-001-01",
"2020-01-001",
"2020-01-01T001",
"2020-01-01T01:001",
"2020-01-01T01:01:001",
// valid, but forms not supported in Temporal:
"2020-W01-1",
"2020-001",
"+0002020-01-01",
// valid, but this calendar must not exist:
"2020-01-01[u-ca=notexist]",
// may be valid in other contexts, but insufficient information for PlainDate:
"2020-01",
"+002020-01",
"01-01",
"2020-W01",
"P1Y",
"-P12Y",
// valid, but outside the supported range:
"-999999-01-01",
"+999999-01-01",
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
for (const arg of invalidStrings) {
assert.throws(
RangeError,
() => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }),
`"${arg}" should not be a valid ISO string for a PlainDate`
);
}

View File

@ -1,29 +0,0 @@
// 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.plaintime.prototype.tozoneddatetime
description: >
More than one calendar annotation is not syntactical if any have the criical
flag
features: [Temporal]
---*/
const invalidStrings = [
"1970-01-01[u-ca=iso8601][!u-ca=iso8601]",
"1970-01-01[!u-ca=iso8601][u-ca=iso8601]",
"1970-01-01[UTC][u-ca=iso8601][!u-ca=iso8601]",
"1970-01-01[u-ca=iso8601][foo=bar][!u-ca=iso8601]",
"1970-01-01T00:00[u-ca=iso8601][!u-ca=iso8601]",
"1970-01-01T00:00[!u-ca=iso8601][u-ca=iso8601]",
"1970-01-01T00:00[UTC][u-ca=iso8601][!u-ca=iso8601]",
"1970-01-01T00:00[u-ca=iso8601][foo=bar][!u-ca=iso8601]",
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }),
`reject more than one calendar annotation if any critical: ${arg}`
);
});

View File

@ -1,25 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: More than one time zone annotation is not syntactical
features: [Temporal]
---*/
const invalidStrings = [
"1970-01-01[UTC][UTC]",
"1970-01-01T00:00[UTC][UTC]",
"1970-01-01T00:00[!UTC][UTC]",
"1970-01-01T00:00[UTC][!UTC]",
"1970-01-01T00:00[UTC][u-ca=iso8601][UTC]",
"1970-01-01T00:00[UTC][foo=bar][UTC]",
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }),
`reject more than one time zone annotation: ${arg}`
);
});

View File

@ -1,26 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: Time separator in string argument can vary
features: [Temporal]
---*/
const tests = [
["2000-05-02T15:23", "uppercase T"],
["2000-05-02t15:23", "lowercase T"],
["2000-05-02 15:23", "space between date and time"],
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
tests.forEach(([arg, description]) => {
const result = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" });
assert.sameValue(
result.epochNanoseconds,
957_270_896_987_654_321n,
`variant time separators (${description})`
);
});

View File

@ -1,35 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: Various forms of time zone annotation; critical flag has no effect
features: [Temporal]
---*/
const tests = [
["2000-05-02[Asia/Kolkata]", "named, with no time"],
["2000-05-02[!Europe/Vienna]", "named, with ! and no time"],
["2000-05-02[+00:00]", "numeric, with no time"],
["2000-05-02[!-02:30]", "numeric, with ! and no time"],
["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"],
["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"],
["2000-05-02T15:23[-02:30]", "numeric, with no offset"],
["2000-05-02T15:23[!+00:00]", "numeric, with ! and no offset"],
["2000-05-02T15:23+00:00[America/New_York]", "named, with offset"],
["2000-05-02T15:23+00:00[!UTC]", "named, with offset and !"],
["2000-05-02T15:23+00:00[+01:00]", "numeric, with offset"],
["2000-05-02T15:23+00:00[!-08:00]", "numeric, with offset and !"],
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
tests.forEach(([arg, description]) => {
const result = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" });
assert.sameValue(
result.epochNanoseconds,
957_270_896_987_654_321n,
`time zone annotation (${description})`
);
});

View File

@ -1,29 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: Various forms of unknown annotation
features: [Temporal]
---*/
const tests = [
["2000-05-02[foo=bar]", "without time"],
["2000-05-02T15:23[foo=bar]", "alone"],
["2000-05-02T15:23[UTC][foo=bar]", "with time zone"],
["2000-05-02T15:23[u-ca=iso8601][foo=bar]", "with calendar"],
["2000-05-02T15:23[UTC][foo=bar][u-ca=iso8601]", "with time zone and calendar"],
["2000-05-02T15:23[foo=bar][_foo-bar0=Ignore-This-999999999999]", "with another unknown annotation"],
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
tests.forEach(([arg, description]) => {
const result = instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" });
assert.sameValue(
result.epochNanoseconds,
957_270_896_987_654_321n,
`unknown annotation (${description})`
);
});

View File

@ -1,21 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: RangeError thrown if a string with UTC designator is used as a PlainDate
features: [Temporal, arrow-function]
---*/
const invalidStrings = [
"2019-10-01T09:00:00Z",
"2019-10-01T09:00:00Z[UTC]",
];
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }),
"String with UTC designator should not be valid as a PlainDate"
);
});

View File

@ -1,40 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: >
Appropriate error thrown when argument cannot be converted to a valid string
or property bag for PlainDate
features: [BigInt, Symbol, Temporal]
---*/
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const primitiveTests = [
[null, "null"],
[true, "boolean"],
["", "empty string"],
[1, "number that doesn't convert to a valid ISO string"],
[1n, "bigint"],
];
for (const [arg, description] of primitiveTests) {
assert.throws(
typeof arg === 'string' ? RangeError : TypeError,
() => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }),
`${description} does not convert to a valid ISO string`
);
}
const typeErrorTests = [
[undefined, "undefined"], // plainDate property is required
[Symbol(), "symbol"],
[{}, "plain object"],
[Temporal.PlainDate, "Temporal.PlainDate, object"],
[Temporal.PlainDate.prototype, "Temporal.PlainDate.prototype, object"],
];
for (const [arg, description] of typeErrorTests) {
assert.throws(TypeError, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }), `${description} is not a valid property bag and does not convert to a string`);
}

View File

@ -1,19 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: An exception from TimeZone#getOffsetNanosecondsFor() is propagated.
features: [Temporal]
---*/
class TZ extends Temporal.TimeZone {
constructor() { super("UTC") }
getOffsetNanosecondsFor() { throw new Test262Error() }
}
const tz = new TZ();
const arg = new Temporal.ZonedDateTime(0n, tz);
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
assert.throws(Test262Error, () => instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" }));

View File

@ -1,37 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: Getters are not called when converting a ZonedDateTime to a PlainDate.
includes: [compareArray.js]
features: [Temporal]
---*/
const actual = [];
const prototypeDescrs = Object.getOwnPropertyDescriptors(Temporal.ZonedDateTime.prototype);
const getters = ["year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", "calendar"];
for (const property of getters) {
Object.defineProperty(Temporal.ZonedDateTime.prototype, property, {
get() {
actual.push(`get ${property}`);
const value = prototypeDescrs[property].get.call(this);
return {
toString() {
actual.push(`toString ${property}`);
return value.toString();
},
valueOf() {
actual.push(`valueOf ${property}`);
return value;
},
};
},
});
}
const arg = new Temporal.ZonedDateTime(0n, "UTC");
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
instance.toZonedDateTime({ plainDate: arg, timeZone: "UTC" });
assert.compareArray(actual, []);

View File

@ -1,16 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: RangeError thrown if time zone reports an offset that is not an integer number of nanoseconds
features: [Temporal]
includes: [temporalHelpers.js]
---*/
[3600_000_000_000.5, NaN, -Infinity, Infinity].forEach((wrongOffset) => {
const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset);
const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
assert.throws(RangeError, () => time.toZonedDateTime({ plainDate: datetime, timeZone: "UTC" }));
});

View File

@ -1,20 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: TypeError thrown if timeZone.getOffsetNanosecondsFor is not callable
features: [BigInt, Symbol, Temporal, arrow-function]
---*/
[undefined, null, true, Math.PI, 'string', Symbol('sym'), 42n, {}].forEach((notCallable) => {
const timeZone = new Temporal.TimeZone("UTC");
const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
timeZone.getOffsetNanosecondsFor = notCallable;
assert.throws(
TypeError,
() => time.toZonedDateTime({ plainDate: datetime, timeZone: "UTC" }),
`Uncallable ${notCallable === null ? 'null' : typeof notCallable} getOffsetNanosecondsFor should throw TypeError`
);
});

View File

@ -1,16 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: RangeError thrown if time zone reports an offset that is out of range
features: [Temporal]
includes: [temporalHelpers.js]
---*/
[-86400_000_000_000, 86400_000_000_000].forEach((wrongOffset) => {
const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset);
const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
assert.throws(RangeError, () => time.toZonedDateTime({ plainDate: datetime, timeZone: "UTC" }));
});

View File

@ -1,25 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: TypeError thrown if time zone reports an offset that is not a Number
features: [Temporal]
includes: [temporalHelpers.js]
---*/
[
undefined,
null,
true,
"+01:00",
Symbol(),
3600_000_000_000n,
{},
{ valueOf() { return 3600_000_000_000; } },
].forEach((wrongOffset) => {
const timeZone = TemporalHelpers.specificOffsetTimeZone(wrongOffset);
const time = new Temporal.PlainTime(12, 34, 56, 987, 654, 321);
const datetime = new Temporal.ZonedDateTime(1_000_000_000_987_654_321n, timeZone);
assert.throws(TypeError, () => time.toZonedDateTime({ plainDate: datetime, timeZone: "UTC" }));
});

View File

@ -1,24 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.tozoneddatetime
description: Basic tests for toZonedDateTime().
features: [Temporal]
---*/
const plainTime = Temporal.PlainTime.from('12:00');
const plainDate = Temporal.PlainDate.from('2020-07-08');
const timeZone = Temporal.TimeZone.from('-07:00');
const objects = plainTime.toZonedDateTime({ timeZone, plainDate });
assert.sameValue(objects.epochNanoseconds, 1594234800000000000n, "objects: epochNanoseconds");
assert.sameValue(objects.getTimeZone(), timeZone, "objects: timeZone");
const timeZoneString = plainTime.toZonedDateTime({ timeZone: "-07:00", plainDate });
assert.sameValue(timeZoneString.epochNanoseconds, 1594234800000000000n, "timeZone string: epochNanoseconds");
assert.sameValue(timeZoneString.timeZoneId, "-07:00", "timeZone string: timeZone");
const plainDateString = plainTime.toZonedDateTime({ timeZone, plainDate: "2020-07-08" });
assert.sameValue(plainDateString.epochNanoseconds, 1594234800000000000n, "plainDate string: epochNanoseconds");
assert.sameValue(plainDateString.getTimeZone(), timeZone, "plainDate string: timeZone");

View File

@ -1,24 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: Throw a TypeError if the receiver is invalid
features: [Symbol, Temporal]
---*/
const toZonedDateTime = Temporal.PlainTime.prototype.toZonedDateTime;
assert.sameValue(typeof toZonedDateTime, "function");
const args = [{ plainDate: "2022-05-19", timeZone: "UTC" }];
assert.throws(TypeError, () => toZonedDateTime.apply(undefined, args), "undefined");
assert.throws(TypeError, () => toZonedDateTime.apply(null, args), "null");
assert.throws(TypeError, () => toZonedDateTime.apply(true, args), "true");
assert.throws(TypeError, () => toZonedDateTime.apply("", args), "empty string");
assert.throws(TypeError, () => toZonedDateTime.apply(Symbol(), args), "symbol");
assert.throws(TypeError, () => toZonedDateTime.apply(1, args), "1");
assert.throws(TypeError, () => toZonedDateTime.apply({}, args), "plain object");
assert.throws(TypeError, () => toZonedDateTime.apply(Temporal.PlainTime, args), "Temporal.PlainTime");
assert.throws(TypeError, () => toZonedDateTime.apply(Temporal.PlainTime.prototype, args), "Temporal.PlainTime.prototype");

View File

@ -1,33 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: >
Tests that Temporal.PlainTime.prototype.toZonedDateTime
meets the requirements for built-in objects defined by the
introduction of chapter 17 of the ECMAScript Language Specification.
info: |
Built-in functions that are not constructors do not have a "prototype" property unless
otherwise specified in the description of a particular function.
Unless specified otherwise, a built-in object that is callable as a function is a built-in
function object with the characteristics described in 10.3. Unless specified otherwise, the
[[Extensible]] internal slot of a built-in object initially has the value true.
Unless otherwise specified every built-in function and every built-in constructor has the
Function prototype object [...] as the value of its [[Prototype]] internal slot.
features: [Temporal]
---*/
assert.sameValue(Object.isExtensible(Temporal.PlainTime.prototype.toZonedDateTime),
true, "Built-in objects must be extensible.");
assert.sameValue(Object.prototype.toString.call(Temporal.PlainTime.prototype.toZonedDateTime),
"[object Function]", "Object.prototype.toString");
assert.sameValue(Object.getPrototypeOf(Temporal.PlainTime.prototype.toZonedDateTime),
Function.prototype, "prototype");
assert.sameValue(Temporal.PlainTime.prototype.toZonedDateTime.hasOwnProperty("prototype"),
false, "prototype property");

View File

@ -1,16 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: >
Calendar.dateFromFields method is called with undefined as the options value
when call originates internally
includes: [temporalHelpers.js]
features: [Temporal]
---*/
const calendar = TemporalHelpers.calendarFromFieldsUndefinedOptions();
const instance = new Temporal.PlainTime(12, 34, 56, 987, 654, 321, calendar);
instance.toZonedDateTime({ plainDate: { year: 2000, month: 5, day: 3, calendar }, timeZone: new Temporal.TimeZone("UTC") });
assert.sameValue(calendar.dateFromFieldsCallCount, 1);

View File

@ -1,31 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: Verify the result of calendar.fields() is treated correctly.
info: |
sec-temporal.plaintime.prototype.tozoneddatetime step 5:
3. Let _temporalDate_ be ? ToTemporalDate(_temporalDateLike_).
sec-temporal-totemporaldate step 2.c:
c. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"monthCode"*, *"year"* »).
sec-temporal-calendarfields step 4:
4. Let _result_ be ? IterableToList(_fieldsArray_).
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const expected = [
"day",
"month",
"monthCode",
"year",
];
const time = new Temporal.PlainTime(13, 3);
const calendar = TemporalHelpers.calendarFieldsIterable();
time.toZonedDateTime({ plainDate: { year: 2000, month: 5, day: 3, calendar }, timeZone: "UTC" });
assert.sameValue(calendar.fieldsCallCount, 1, "fields() method called once");
assert.compareArray(calendar.fieldsCalledWith[0], expected, "fields() method called with correct args");
assert(calendar.iteratorExhausted[0], "iterated through the whole iterable");

View File

@ -1,27 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
info: |
sec-temporal.plaintime.prototype.tozoneddatetime step 5:
5. Let _temporalDate_ be ? ToTemporalDate(_temporalDateLike_).
sec-temporal-totemporaldate step 2.c:
c. Let _calendar_ be ? GetTemporalCalendarWithISODefault(_item_).
sec-temporal-gettemporalcalendarwithisodefault step 2:
2. Return ? ToTemporalCalendarWithISODefault(_calendar_).
sec-temporal-totemporalcalendarwithisodefault step 2:
3. Return ? ToTemporalCalendar(_temporalCalendarLike_).
sec-temporal-totemporalcalendar step 1.a:
a. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then
i. Return _temporalCalendarLike_.[[Calendar]].
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject, calendar) => {
const time = new Temporal.PlainTime(13, 3);
const result = time.toZonedDateTime({ timeZone: "UTC", plainDate: { year: 2000, month: 5, day: 3, calendar: temporalObject } });
assert.sameValue(result.getCalendar(), calendar, "Temporal object coerced to calendar");
});

View File

@ -1,46 +0,0 @@
// Copyright (C) 2024 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: >
UTC offset shift returned by adjacent invocations of getOffsetNanosecondsFor
in DisambiguatePossibleInstants can be at most 24 hours.
features: [Temporal]
info: |
DisambiguatePossibleInstants:
18. If abs(_nanoseconds_) > nsPerDay, throw a *RangeError* exception.
---*/
let calls = 0;
class Shift24Hour extends Temporal.TimeZone {
id = 'TestTimeZone';
_shiftEpochNs = 12n * 3600n * 1_000_000_000n; // 1970-01-01T12:00Z
constructor() {
super('UTC');
}
getOffsetNanosecondsFor(instant) {
calls++;
if (instant.epochNanoseconds < this._shiftEpochNs) return -12 * 3600e9;
return 12 * 3600e9;
}
getPossibleInstantsFor(plainDateTime) {
const [utcInstant] = super.getPossibleInstantsFor(plainDateTime);
const { year, month, day } = plainDateTime;
if (year < 1970) return [utcInstant.subtract({ hours: 12 })];
if (year === 1970 && month === 1 && day === 1) return [];
return [utcInstant.add({ hours: 12 })];
}
}
const timeZone = new Shift24Hour();
const instance = new Temporal.PlainTime(12);
instance.toZonedDateTime({ timeZone, plainDate: new Temporal.PlainDate(1970, 1, 1) });
assert(calls >= 2, "getOffsetNanosecondsFor should be called at least twice");

View File

@ -1,41 +0,0 @@
// Copyright (C) 2024 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: >
UTC offset shift returned by adjacent invocations of getOffsetNanosecondsFor
in DisambiguatePossibleInstants cannot be greater than 24 hours.
features: [Temporal]
info: |
DisambiguatePossibleInstants:
18. If abs(_nanoseconds_) > nsPerDay, throw a *RangeError* exception.
---*/
class ShiftLonger24Hour extends Temporal.TimeZone {
id = 'TestTimeZone';
_shiftEpochNs = 12n * 3600n * 1_000_000_000n; // 1970-01-01T12:00Z
constructor() {
super('UTC');
}
getOffsetNanosecondsFor(instant) {
if (instant.epochNanoseconds < this._shiftEpochNs) return -12 * 3600e9;
return 12 * 3600e9 + 1;
}
getPossibleInstantsFor(plainDateTime) {
const [utcInstant] = super.getPossibleInstantsFor(plainDateTime);
const { year, month, day } = plainDateTime;
if (year < 1970) return [utcInstant.subtract({ hours: 12 })];
if (year === 1970 && month === 1 && day === 1) return [];
return [utcInstant.add({ hours: 12, nanoseconds: 1 })];
}
}
const timeZone = new ShiftLonger24Hour();
const instance = new Temporal.PlainTime(12);
assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone, plainDate: new Temporal.PlainDate(1970, 1, 1) }), "RangeError should be thrown");

View File

@ -1,55 +0,0 @@
// 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.plaintime.prototype.tozoneddatetime
description: >
Time zone's getPossibleInstantsFor is called with a PlainDateTime with the
built-in ISO 8601 calendar
features: [Temporal]
info: |
DisambiguatePossibleInstants:
2. Let _n_ be _possibleInstants_'s length.
...
5. Assert: _n_ = 0.
...
19. If _disambiguation_ is *"earlier"*, then
...
c. Let _earlierDateTime_ be ! CreateTemporalDateTime(..., *"iso8601"*).
d. Set _possibleInstants_ to ? GetPossibleInstantsFor(_timeZone_, _earlierDateTime_).
...
20. Assert: _disambiguation_ is *"compatible"* or *"later"*.
...
23. Let _laterDateTime_ be ! CreateTemporalDateTime(..., *"iso8601"*).
24. Set _possibleInstants_ to ? GetPossibleInstantsFor(_timeZone_, _laterDateTime_).
---*/
class SkippedDateTime extends Temporal.TimeZone {
constructor() {
super("UTC");
this.calls = 0;
}
getPossibleInstantsFor(dateTime) {
// Calls occur in pairs. For the first one return no possible instants so
// that DisambiguatePossibleInstants will call it again
if (this.calls++ % 2 == 0) {
return [];
}
assert.sameValue(
dateTime.getISOFields().calendar,
"iso8601",
"getPossibleInstantsFor called with dateTime with built-in ISO 8601 calendar"
);
return super.getPossibleInstantsFor(dateTime);
}
}
const nonBuiltinISOCalendar = new Temporal.Calendar("iso8601");
const timeZone = new SkippedDateTime();
const instance = new Temporal.PlainTime(12, 34, 56);
instance.toZonedDateTime({ timeZone, plainDate: new Temporal.PlainDate(2000, 5, 2, nonBuiltinISOCalendar) });
assert.sameValue(timeZone.calls, 2, "getPossibleInstantsFor should have been called 2 times");

View File

@ -1,50 +0,0 @@
// Copyright (C) 2024 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: >
UTC offset shift returned by getPossibleInstantsFor can be at most 24 hours.
features: [Temporal]
info: |
GetPossibleInstantsFor:
5.b.i. Let _numResults_ be _list_'s length.
ii. If _numResults_ > 1, then
1. Let _epochNs_ be a new empty List.
2. For each value _instant_ in list, do
a. Append _instant_.[[EpochNanoseconds]] to the end of the List _epochNs_.
3. Let _min_ be the least element of the List _epochNs_.
4. Let _max_ be the greatest element of the List _epochNs_.
5. If abs((_max_ - _min_)) > nsPerDay, throw a *RangeError* exception.
---*/
let calls = 0;
class Shift24Hour extends Temporal.TimeZone {
id = 'TestTimeZone';
constructor() {
super('UTC');
}
getOffsetNanosecondsFor(instant) {
return 0;
}
getPossibleInstantsFor(plainDateTime) {
calls++;
const utc = new Temporal.TimeZone("UTC");
const [utcInstant] = utc.getPossibleInstantsFor(plainDateTime);
return [
utcInstant.subtract({ hours: 12 }),
utcInstant.add({ hours: 12 })
];
}
}
const timeZone = new Shift24Hour();
const instance = new Temporal.PlainTime(12);
instance.toZonedDateTime({ timeZone, plainDate: new Temporal.PlainDate(1970, 1, 1) });
assert(calls >= 1, "getPossibleInstantsFor should be called at least once");

View File

@ -1,46 +0,0 @@
// Copyright (C) 2024 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: >
UTC offset shift returned by getPossibleInstantsFor can be at most 24 hours.
features: [Temporal]
info: |
GetPossibleInstantsFor:
5.b.i. Let _numResults_ be _list_'s length.
ii. If _numResults_ > 1, then
1. Let _epochNs_ be a new empty List.
2. For each value _instant_ in list, do
a. Append _instant_.[[EpochNanoseconds]] to the end of the List _epochNs_.
3. Let _min_ be the least element of the List _epochNs_.
4. Let _max_ be the greatest element of the List _epochNs_.
5. If abs((_max_ - _min_)) > nsPerDay, throw a *RangeError* exception.
---*/
class ShiftLonger24Hour extends Temporal.TimeZone {
id = 'TestTimeZone';
constructor() {
super('UTC');
}
getOffsetNanosecondsFor(instant) {
return 0;
}
getPossibleInstantsFor(plainDateTime) {
const utc = new Temporal.TimeZone("UTC");
const [utcInstant] = utc.getPossibleInstantsFor(plainDateTime);
return [
utcInstant.subtract({ hours: 12, nanoseconds: 1 }),
utcInstant.add({ hours: 12 }),
utcInstant, // add a third value in case the implementation doesn't sort
];
}
}
const timeZone = new ShiftLonger24Hour();
const instance = new Temporal.PlainTime(12);
assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone, plainDate: new Temporal.PlainDate(1970, 1, 1) }), "RangeError should be thrown");

View File

@ -1,23 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Throws if any value in the property bag is Infinity or -Infinity
esid: sec-temporal.plaintime.prototype.tozoneddatetime
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(15);
const base = { year: 2000, month: 5, day: 2 };
[Infinity, -Infinity].forEach((inf) => {
["year", "month", "day"].forEach((prop) => {
assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone: "UTC", plainDate: { ...base, [prop]: inf } }), `${prop} property cannot be ${inf}`);
const calls = [];
const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone: "UTC", plainDate: { ...base, [prop]: obj } }));
assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
});
});

View File

@ -1,25 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: Temporal.PlainTime.prototype.toZonedDateTime.length is 1
info: |
Every built-in function object, including constructors, has a "length" property whose value is
an integer. Unless otherwise specified, this value is equal to the largest number of named
arguments shown in the subclause headings for the function description. Optional parameters
(which are indicated with brackets: [ ]) or rest parameters (which are shown using the form
«...name») are not included in the default argument count.
Unless otherwise specified, the "length" property of a built-in function object has the
attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
includes: [propertyHelper.js]
features: [Temporal]
---*/
verifyProperty(Temporal.PlainTime.prototype.toZonedDateTime, "length", {
value: 1,
writable: false,
enumerable: false,
configurable: true,
});

View File

@ -1,23 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: Temporal.PlainTime.prototype.toZonedDateTime.name is "toZonedDateTime".
info: |
Every built-in function object, including constructors, that is not identified as an anonymous
function has a "name" property whose value is a String. Unless otherwise specified, this value
is the name that is given to the function in this specification.
Unless otherwise specified, the "name" property of a built-in function object, if it exists,
has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
includes: [propertyHelper.js]
features: [Temporal]
---*/
verifyProperty(Temporal.PlainTime.prototype.toZonedDateTime, "name", {
value: "toZonedDateTime",
writable: false,
enumerable: false,
configurable: true,
});

View File

@ -1,21 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: >
Temporal.PlainTime.prototype.toZonedDateTime does not implement [[Construct]], is not new-able
info: |
Built-in function objects that are not identified as constructors do not implement the
[[Construct]] internal method unless otherwise specified in the description of a particular
function.
includes: [isConstructor.js]
features: [Reflect.construct, Temporal]
---*/
assert.throws(TypeError, () => {
new Temporal.PlainTime.prototype.toZonedDateTime();
}, "Calling as constructor");
assert.sameValue(isConstructor(Temporal.PlainTime.prototype.toZonedDateTime), false,
"isConstructor(Temporal.PlainTime.prototype.toZonedDateTime)");

View File

@ -1,115 +0,0 @@
// 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.plaintime.prototype.tozoneddatetime
description: User code calls happen in the correct order
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const actual = [];
const expected = [
"get item.plainDate",
"get item.plainDate.calendar",
"has item.plainDate.calendar.dateAdd",
"has item.plainDate.calendar.dateFromFields",
"has item.plainDate.calendar.dateUntil",
"has item.plainDate.calendar.day",
"has item.plainDate.calendar.dayOfWeek",
"has item.plainDate.calendar.dayOfYear",
"has item.plainDate.calendar.daysInMonth",
"has item.plainDate.calendar.daysInWeek",
"has item.plainDate.calendar.daysInYear",
"has item.plainDate.calendar.fields",
"has item.plainDate.calendar.id",
"has item.plainDate.calendar.inLeapYear",
"has item.plainDate.calendar.mergeFields",
"has item.plainDate.calendar.month",
"has item.plainDate.calendar.monthCode",
"has item.plainDate.calendar.monthDayFromFields",
"has item.plainDate.calendar.monthsInYear",
"has item.plainDate.calendar.weekOfYear",
"has item.plainDate.calendar.year",
"has item.plainDate.calendar.yearMonthFromFields",
"has item.plainDate.calendar.yearOfWeek",
"get item.plainDate.calendar.dateFromFields",
"get item.plainDate.calendar.fields",
"call item.plainDate.calendar.fields",
"get item.plainDate.day",
"get item.plainDate.day.valueOf",
"call item.plainDate.day.valueOf",
"get item.plainDate.month",
"get item.plainDate.month.valueOf",
"call item.plainDate.month.valueOf",
"get item.plainDate.monthCode",
"get item.plainDate.monthCode.toString",
"call item.plainDate.monthCode.toString",
"get item.plainDate.year",
"get item.plainDate.year.valueOf",
"call item.plainDate.year.valueOf",
"call item.plainDate.calendar.dateFromFields",
"get item.timeZone",
"has item.timeZone.getOffsetNanosecondsFor",
"has item.timeZone.getPossibleInstantsFor",
"has item.timeZone.id",
"get item.timeZone.getOffsetNanosecondsFor",
"get item.timeZone.getPossibleInstantsFor",
"call item.timeZone.getPossibleInstantsFor",
];
const calendar = TemporalHelpers.calendarObserver(actual, "item.plainDate.calendar");
const instance = new Temporal.PlainTime(2, 30);
const dstTimeZone = TemporalHelpers.springForwardFallBackTimeZone();
const timeZone = TemporalHelpers.timeZoneObserver(actual, "item.timeZone", {
getOffsetNanosecondsFor: dstTimeZone.getOffsetNanosecondsFor,
getPossibleInstantsFor: dstTimeZone.getPossibleInstantsFor,
});
const plainDate = TemporalHelpers.propertyBagObserver(actual, {
year: 2000,
month: 1,
monthCode: "M01",
day: 1,
calendar,
}, "item.plainDate");
instance.toZonedDateTime(TemporalHelpers.propertyBagObserver(actual, {
plainDate,
timeZone,
}, "item"));
assert.compareArray(actual, expected, "order of operations at normal wall-clock time");
actual.splice(0); // clear
const fallBackPlainDate = TemporalHelpers.propertyBagObserver(actual, {
year: 2000,
month: 10,
monthCode: "M10",
day: 29,
calendar,
}, "item.plainDate");
const fallBackInstance = new Temporal.PlainTime(1, 30);
fallBackInstance.toZonedDateTime(TemporalHelpers.propertyBagObserver(actual, {
plainDate: fallBackPlainDate,
timeZone,
}, "item"));
assert.compareArray(actual, expected, "order of operations at repeated wall-clock time");
actual.splice(0); // clear
const springForwardPlainDate = TemporalHelpers.propertyBagObserver(actual, {
year: 2000,
month: 4,
monthCode: "M04",
day: 2,
calendar,
}, "item.plainDate");
instance.toZonedDateTime(TemporalHelpers.propertyBagObserver(actual, {
plainDate: springForwardPlainDate,
timeZone,
}, "item"));
assert.compareArray(actual, expected.concat([
"call item.timeZone.getOffsetNanosecondsFor",
"call item.timeZone.getOffsetNanosecondsFor",
"call item.timeZone.getPossibleInstantsFor",
]), "order of operations at skipped wall-clock time");
actual.splice(0); // clear

View File

@ -1,23 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Throws if any value in the property bag is Infinity or -Infinity
esid: sec-temporal.plaintime.prototype.tozoneddatetime
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/
const instance = new Temporal.PlainTime(15);
const base = { year: 2000, month: 5, day: 2 };
[Infinity, -Infinity].forEach((inf) => {
["year", "month", "day"].forEach((prop) => {
assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone: "UTC", plainDate: { ...base, [prop]: inf } }), `${prop} property cannot be ${inf} in plainDate`);
const calls = [];
const obj = TemporalHelpers.toPrimitiveObserver(calls, inf, prop);
assert.throws(RangeError, () => instance.toZonedDateTime({ timeZone: "UTC", plainDate: { ...base, [prop]: obj } }));
assert.compareArray(calls, [`get ${prop}.valueOf`, `call ${prop}.valueOf`], "it fails after fetching the primitive value");
});
});

View File

@ -1,21 +0,0 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: The "toZonedDateTime" property of Temporal.PlainTime.prototype
includes: [propertyHelper.js]
features: [Temporal]
---*/
assert.sameValue(
typeof Temporal.PlainTime.prototype.toZonedDateTime,
"function",
"`typeof PlainTime.prototype.toZonedDateTime` is `function`"
);
verifyProperty(Temporal.PlainTime.prototype, "toZonedDateTime", {
writable: true,
enumerable: false,
configurable: true,
});

View File

@ -1,14 +0,0 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.plaintime.prototype.tozoneddatetime
description: Time zone names are case insensitive
features: [Temporal]
---*/
const instance = new Temporal.PlainTime();
const timeZone = 'uTc';
const result = instance.toZonedDateTime({ plainDate: new Temporal.PlainDate(2000, 5, 2), timeZone });
assert.sameValue(result.timeZoneId, 'UTC', `Time zone created from string "${timeZone}"`);

Some files were not shown because too many files have changed in this diff Show More