mirror of https://github.com/tc39/test262.git
Temporal: Remove PlainTime.toPlainDateTime/toZonedDateTime methods
See tc39/proposal-temporal#2848
This commit is contained in:
parent
a9c223c60e
commit
7184313667
|
@ -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;
|
|
@ -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");
|
|
@ -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));
|
|
@ -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));
|
||||
}
|
|
@ -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"
|
||||
);
|
|
@ -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'
|
||||
);
|
||||
}
|
|
@ -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);
|
||||
});
|
|
@ -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");
|
|
@ -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}"`);
|
||||
}
|
|
@ -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"
|
||||
);
|
|
@ -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"
|
||||
);
|
||||
}
|
|
@ -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}"`);
|
|
@ -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`);
|
||||
}
|
|
@ -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"
|
||||
);
|
||||
});
|
|
@ -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));
|
|
@ -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}`
|
||||
);
|
||||
});
|
|
@ -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})`
|
||||
);
|
||||
});
|
|
@ -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}`
|
||||
);
|
||||
});
|
|
@ -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`
|
||||
);
|
||||
}
|
|
@ -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`
|
||||
);
|
||||
}
|
|
@ -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}`
|
||||
);
|
||||
});
|
|
@ -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}`
|
||||
);
|
||||
});
|
|
@ -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})`
|
||||
);
|
||||
});
|
|
@ -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})`
|
||||
);
|
||||
});
|
|
@ -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})`
|
||||
);
|
||||
});
|
|
@ -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"
|
||||
);
|
||||
});
|
|
@ -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`);
|
||||
}
|
|
@ -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));
|
|
@ -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, []);
|
|
@ -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));
|
||||
});
|
|
@ -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`
|
||||
);
|
||||
});
|
|
@ -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));
|
||||
});
|
|
@ -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));
|
||||
});
|
|
@ -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");
|
|
@ -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");
|
|
@ -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");
|
|
@ -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);
|
|
@ -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");
|
|
@ -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");
|
||||
});
|
|
@ -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");
|
||||
});
|
||||
});
|
|
@ -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,
|
||||
});
|
|
@ -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"
|
||||
);
|
|
@ -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,
|
||||
});
|
|
@ -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)");
|
|
@ -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,
|
||||
});
|
|
@ -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"
|
||||
);
|
||||
});
|
|
@ -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;
|
|
@ -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");
|
|
@ -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" }));
|
|
@ -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" }));
|
||||
}
|
|
@ -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"
|
||||
);
|
|
@ -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'
|
||||
);
|
||||
}
|
|
@ -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");
|
||||
});
|
|
@ -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");
|
|
@ -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");
|
|
@ -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}"`);
|
||||
}
|
|
@ -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"
|
||||
);
|
|
@ -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"
|
||||
);
|
||||
}
|
|
@ -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}"`);
|
|
@ -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`);
|
||||
}
|
|
@ -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"
|
||||
);
|
||||
});
|
|
@ -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");
|
|
@ -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" }));
|
|
@ -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}`
|
||||
);
|
||||
});
|
|
@ -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})`
|
||||
);
|
||||
});
|
|
@ -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}`
|
||||
);
|
||||
});
|
|
@ -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`
|
||||
);
|
||||
}
|
|
@ -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`
|
||||
);
|
||||
}
|
|
@ -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}`
|
||||
);
|
||||
});
|
|
@ -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}`
|
||||
);
|
||||
});
|
|
@ -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})`
|
||||
);
|
||||
});
|
|
@ -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})`
|
||||
);
|
||||
});
|
|
@ -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})`
|
||||
);
|
||||
});
|
|
@ -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"
|
||||
);
|
||||
});
|
|
@ -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`);
|
||||
}
|
|
@ -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" }));
|
|
@ -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, []);
|
|
@ -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" }));
|
||||
});
|
|
@ -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`
|
||||
);
|
||||
});
|
|
@ -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" }));
|
||||
});
|
|
@ -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" }));
|
||||
});
|
|
@ -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");
|
|
@ -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");
|
|
@ -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");
|
|
@ -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);
|
|
@ -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");
|
|
@ -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");
|
||||
});
|
|
@ -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");
|
|
@ -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");
|
|
@ -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");
|
|
@ -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");
|
|
@ -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");
|
|
@ -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");
|
||||
});
|
||||
});
|
|
@ -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,
|
||||
});
|
|
@ -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,
|
||||
});
|
|
@ -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)");
|
|
@ -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
|
|
@ -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");
|
||||
});
|
||||
});
|
|
@ -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,
|
||||
});
|
|
@ -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
Loading…
Reference in New Issue