diff --git a/docs/cookbook/nextWeeklyOccurrence.mjs b/docs/cookbook/nextWeeklyOccurrence.mjs index b34f7f8f42..5f8fcc8a57 100644 --- a/docs/cookbook/nextWeeklyOccurrence.mjs +++ b/docs/cookbook/nextWeeklyOccurrence.mjs @@ -21,7 +21,7 @@ function nextWeeklyOccurrence(now, weekday, eventTime, eventTimeZone) { nextOccurrence = nextOccurrence.add({ days: 7 }); } - return eventTimeZone.getInstantFor(nextOccurrence).toZonedDateTime(now.timeZone, now.calendar).toDateTime(); + return eventTimeZone.getInstantFor(nextOccurrence).toZonedDateTime(now).toDateTime(); } // "Weekly on Thursdays at 08:45 California time": diff --git a/polyfill/lib/instant.mjs b/polyfill/lib/instant.mjs index 49d79ea186..006b5f7ea1 100644 --- a/polyfill/lib/instant.mjs +++ b/polyfill/lib/instant.mjs @@ -233,16 +233,33 @@ export class Instant { valueOf() { throw new TypeError('use compare() or equals() to compare Temporal.Instant'); } - toZonedDateTime(temporalTimeZoneLike, calendarLike) { + toZonedDateTime(item) { if (!ES.IsTemporalInstant(this)) throw new TypeError('invalid receiver'); - const timeZone = ES.ToTemporalTimeZone(temporalTimeZoneLike); + if (ES.Type(item) !== 'Object') { + throw new TypeError('invalid argument in toZonedDateTime'); + } + const calendarLike = item.calendar; + if (calendarLike === undefined) { + throw new TypeError('missing calendar property in toZonedDateTime'); + } const calendar = ES.ToTemporalCalendar(calendarLike); + const temporalTimeZoneLike = item.timeZone; + if (temporalTimeZoneLike === undefined) { + throw new TypeError('missing timeZone property in toZonedDateTime'); + } + const timeZone = ES.ToTemporalTimeZone(temporalTimeZoneLike); const TemporalZonedDateTime = GetIntrinsic('%Temporal.ZonedDateTime%'); return new TemporalZonedDateTime(GetSlot(this, EPOCHNANOSECONDS), timeZone, calendar); } - toZonedDateTimeISO(temporalTimeZoneLike) { + toZonedDateTimeISO(item) { if (!ES.IsTemporalInstant(this)) throw new TypeError('invalid receiver'); - const timeZone = ES.ToTemporalTimeZone(temporalTimeZoneLike); + if (ES.Type(item) === 'Object') { + const timeZoneProperty = item.timeZone; + if (timeZoneProperty !== undefined) { + item = timeZoneProperty; + } + } + const timeZone = ES.ToTemporalTimeZone(item); const calendar = GetISO8601Calendar(); const TemporalZonedDateTime = GetIntrinsic('%Temporal.ZonedDateTime%'); return new TemporalZonedDateTime(GetSlot(this, EPOCHNANOSECONDS), timeZone, calendar); diff --git a/polyfill/test/Instant/prototype/toZonedDateTime/calendar-convert.js b/polyfill/test/Instant/prototype/toZonedDateTime/calendar-convert.js index 698c9f78f3..6967e0c161 100644 --- a/polyfill/test/Instant/prototype/toZonedDateTime/calendar-convert.js +++ b/polyfill/test/Instant/prototype/toZonedDateTime/calendar-convert.js @@ -24,7 +24,7 @@ for (const [input, output] of values) { return calendar; }; - const zdt = instant.toZonedDateTime("UTC", input); + const zdt = instant.toZonedDateTime({ timeZone: "UTC", calendar: input }); assert.sameValue(called, 1); assert.sameValue(zdt.calendar, calendar); } @@ -33,4 +33,4 @@ Temporal.Calendar.from = function() { throw new Test262Error("Should not call Calendar.from"); }; -assert.throws(TypeError, () => instant.toZonedDateTime("UTC", Symbol())); +assert.throws(TypeError, () => instant.toZonedDateTime({ timeZone: "UTC", calendar: Symbol() })); diff --git a/polyfill/test/Instant/prototype/toZonedDateTime/calendar-from-invalid-result.js b/polyfill/test/Instant/prototype/toZonedDateTime/calendar-from-invalid-result.js index 1665b36a38..6ad5265f3e 100644 --- a/polyfill/test/Instant/prototype/toZonedDateTime/calendar-from-invalid-result.js +++ b/polyfill/test/Instant/prototype/toZonedDateTime/calendar-from-invalid-result.js @@ -26,6 +26,6 @@ for (const [value, description] of values) { return value; }; - assert.throws(TypeError, () => instant.toZonedDateTime(timeZone, "test"), description); + assert.throws(TypeError, () => instant.toZonedDateTime({ timeZone, calendar: "test" }), description); assert.sameValue(called, 1); } diff --git a/polyfill/test/Instant/prototype/toZonedDateTime/calendar-from-undefined.js b/polyfill/test/Instant/prototype/toZonedDateTime/calendar-from-undefined.js index e65c28f1ee..4e66614ace 100644 --- a/polyfill/test/Instant/prototype/toZonedDateTime/calendar-from-undefined.js +++ b/polyfill/test/Instant/prototype/toZonedDateTime/calendar-from-undefined.js @@ -37,7 +37,7 @@ Object.defineProperty(Temporal.Calendar, "from", { }, }); -const result = instant.toZonedDateTime(timeZone, "japanese"); +const result = instant.toZonedDateTime({ timeZone, calendar: "japanese" }); assert.sameValue(result.epochNanoseconds, instant.epochNanoseconds); assert.sameValue(result.calendar instanceof Temporal.Calendar, true); assert.sameValue(result.calendar.id, "japanese"); diff --git a/polyfill/test/Instant/prototype/toZonedDateTime/calendar-function.js b/polyfill/test/Instant/prototype/toZonedDateTime/calendar-function.js index 2bd81c2594..98bc131800 100644 --- a/polyfill/test/Instant/prototype/toZonedDateTime/calendar-function.js +++ b/polyfill/test/Instant/prototype/toZonedDateTime/calendar-function.js @@ -35,7 +35,7 @@ Object.defineProperty(Temporal.Calendar, "from", { }, }); -const result = instant.toZonedDateTime(timeZone, calendar); +const result = instant.toZonedDateTime({ timeZone, calendar }); assert.sameValue(result.epochNanoseconds, instant.epochNanoseconds); assert.sameValue(result.calendar, calendar); diff --git a/polyfill/test/Instant/prototype/toZonedDateTime/calendar-object.js b/polyfill/test/Instant/prototype/toZonedDateTime/calendar-object.js index a7b850970c..f9fe1123ed 100644 --- a/polyfill/test/Instant/prototype/toZonedDateTime/calendar-object.js +++ b/polyfill/test/Instant/prototype/toZonedDateTime/calendar-object.js @@ -35,7 +35,7 @@ Object.defineProperty(Temporal.Calendar, "from", { }, }); -const result = instant.toZonedDateTime(timeZone, calendar); +const result = instant.toZonedDateTime({ timeZone, calendar }); assert.sameValue(result.epochNanoseconds, instant.epochNanoseconds); assert.sameValue(result.calendar, calendar); diff --git a/polyfill/test/Instant/prototype/toZonedDateTime/calendar.js b/polyfill/test/Instant/prototype/toZonedDateTime/calendar.js index 411427898a..d2948aec84 100644 --- a/polyfill/test/Instant/prototype/toZonedDateTime/calendar.js +++ b/polyfill/test/Instant/prototype/toZonedDateTime/calendar.js @@ -8,10 +8,10 @@ includes: [compareArray.js] const actual = []; const expected = [ - "get Temporal.TimeZone.from", - "call Temporal.TimeZone.from", "get Temporal.Calendar.from", "call Temporal.Calendar.from", + "get Temporal.TimeZone.from", + "call Temporal.TimeZone.from", ]; const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789Z"); @@ -57,7 +57,7 @@ Object.defineProperty(Temporal.Calendar, "from", { }, }); -const result = instant.toZonedDateTime("UTC", "iso8601"); +const result = instant.toZonedDateTime({ timeZone: "UTC", calendar: "iso8601" }); assert.sameValue(result.epochNanoseconds, instant.epochNanoseconds); assert.sameValue(result.calendar, calendar); diff --git a/polyfill/test/Instant/prototype/toZonedDateTime/length.js b/polyfill/test/Instant/prototype/toZonedDateTime/length.js index 40a88e4e77..f29a5601fc 100644 --- a/polyfill/test/Instant/prototype/toZonedDateTime/length.js +++ b/polyfill/test/Instant/prototype/toZonedDateTime/length.js @@ -16,7 +16,7 @@ includes: [propertyHelper.js] ---*/ verifyProperty(Temporal.Instant.prototype.toZonedDateTime, "length", { - value: 2, + value: 1, writable: false, enumerable: false, configurable: true, diff --git a/polyfill/test/Instant/prototype/toZonedDateTime/plain-custom-timezone.js b/polyfill/test/Instant/prototype/toZonedDateTime/plain-custom-timezone.js index 8afcfd8040..83494ab136 100644 --- a/polyfill/test/Instant/prototype/toZonedDateTime/plain-custom-timezone.js +++ b/polyfill/test/Instant/prototype/toZonedDateTime/plain-custom-timezone.js @@ -28,7 +28,7 @@ const timeZone = new Proxy({ }, }); -const result = instant.toZonedDateTime(timeZone, calendar); +const result = instant.toZonedDateTime({ timeZone, calendar }); assert.sameValue(result.epochNanoseconds, instant.epochNanoseconds); assert.compareArray(actual, expected); diff --git a/polyfill/test/instant.mjs b/polyfill/test/instant.mjs index fcbdefd80d..95b26a0eb7 100644 --- a/polyfill/test/instant.mjs +++ b/polyfill/test/instant.mjs @@ -1307,20 +1307,20 @@ describe('Instant', () => { describe('Instant.toZonedDateTime() works', () => { const inst = Instant.from('1976-11-18T14:23:30.123456789Z'); it('throws without parameter', () => { - throws(() => inst.toZonedDateTime(), RangeError); + throws(() => inst.toZonedDateTime(), TypeError); }); - it('throws with only one parameter', () => { - throws(() => inst.toZonedDateTime('Asia/Singapore')); + it('throws with a string parameter', () => { + throws(() => inst.toZonedDateTime('Asia/Singapore'), TypeError); }); it('time zone parameter UTC', () => { - const tz = Temporal.TimeZone.from('UTC'); - const zdt = inst.toZonedDateTime(tz, 'gregory'); + const timeZone = Temporal.TimeZone.from('UTC'); + const zdt = inst.toZonedDateTime({ timeZone, calendar: 'gregory' }); equal(inst.epochNanoseconds, zdt.epochNanoseconds); equal(`${zdt}`, '1976-11-18T14:23:30.123456789+00:00[UTC][c=gregory]'); }); it('time zone parameter non-UTC', () => { - const tz = Temporal.TimeZone.from('America/New_York'); - const zdt = inst.toZonedDateTime(tz, 'gregory'); + const timeZone = Temporal.TimeZone.from('America/New_York'); + const zdt = inst.toZonedDateTime({ timeZone, calendar: 'gregory' }); equal(inst.epochNanoseconds, zdt.epochNanoseconds); equal(`${zdt}`, '1976-11-18T09:23:30.123456789-05:00[America/New_York][c=gregory]'); }); diff --git a/polyfill/test/zoneddatetime.mjs b/polyfill/test/zoneddatetime.mjs index b16165d4d1..b7c317ecc3 100644 --- a/polyfill/test/zoneddatetime.mjs +++ b/polyfill/test/zoneddatetime.mjs @@ -1286,7 +1286,10 @@ describe('ZonedDateTime', () => { equal(`${zdt.toDate()}`, '2019-10-29'); }); it('preserves the calendar', () => { - const zdt = Temporal.Instant.from('2019-10-29T09:46:38.271986102Z').toZonedDateTime(tz, 'gregory'); + const zdt = Temporal.Instant.from('2019-10-29T09:46:38.271986102Z').toZonedDateTime({ + timeZone: tz, + calendar: 'gregory' + }); equal(zdt.toDate().calendar.id, 'gregory'); }); }); @@ -1302,7 +1305,10 @@ describe('ZonedDateTime', () => { equal(`${zdt.toYearMonth()}`, '2019-10'); }); it('preserves the calendar', () => { - const zdt = Temporal.Instant.from('2019-10-29T09:46:38.271986102Z').toZonedDateTime(tz, 'gregory'); + const zdt = Temporal.Instant.from('2019-10-29T09:46:38.271986102Z').toZonedDateTime({ + timeZone: tz, + calendar: 'gregory' + }); equal(zdt.toYearMonth().calendar.id, 'gregory'); }); }); @@ -1312,7 +1318,10 @@ describe('ZonedDateTime', () => { equal(`${zdt.toMonthDay()}`, '10-29'); }); it('preserves the calendar', () => { - const zdt = Temporal.Instant.from('2019-10-29T09:46:38.271986102Z').toZonedDateTime(tz, 'gregory'); + const zdt = Temporal.Instant.from('2019-10-29T09:46:38.271986102Z').toZonedDateTime({ + timeZone: tz, + calendar: 'gregory' + }); equal(zdt.toMonthDay().calendar.id, 'gregory'); }); }); diff --git a/spec/instant.html b/spec/instant.html index 37d8cc2198..8fc7d67c40 100644 --- a/spec/instant.html +++ b/spec/instant.html @@ -446,30 +446,42 @@

Temporal.Instant.prototype.valueOf ( )

-

Temporal.Instant.prototype.toZonedDateTime ( _temporalTimeZoneLike_, _calendarLike_ )

+

Temporal.Instant.prototype.toZonedDateTime ( _item_ )

- The `toZonedDateTime` method takes two arguments, _temporalTimeZoneLike_ and _calendarLike_. + The `toZonedDateTime` method takes one argument _item_. The following steps are taken:

1. Let _instant_ be the *this* value. 1. Perform ? RequireInternalSlot(_instant_, [[InitializedTemporalInstant]]). - 1. Let _timeZone_ be ? ToTemporalTimeZone(_temporalTimeZoneLike_). + 1. If Type(_item_) is not Object, then + 1. Throw a *TypeError* exception. + 1. Let _calendarLike_ be ? Get(_item_, *"calendar"*). + 1. If _calendarLike_ is *undefined*, then + 1. Throw a *TypeError* exception. 1. Let _calendar_ be ? ToTemporalCalendar(_calendarLike_). + 1. Let _temporalTimeZoneLike_ be ? Get(_item_, *"timeZone"*). + 1. If _temporalTimeZoneLike_ is *undefined*, then + 1. Throw a *TypeError* exception. + 1. Let _timeZone_ be ? ToTemporalTimeZone(_temporalTimeZoneLike_). 1. Return ? CreateTemporalZonedDateTime(_instant_.[[Nanoseconds]], _timeZone_, _calendar_).
-

Temporal.Instant.prototype.toZonedDateTimeISO ( _temporalTimeZoneLike_ )

+

Temporal.Instant.prototype.toZonedDateTimeISO ( _item_ )

- The `toZonedDateTimeISO` method takes one argument _temporalTimeZoneLike_. + The `toZonedDateTimeISO` method takes one argument _item_. The following steps are taken:

1. Let _instant_ be the *this* value. 1. Perform ? RequireInternalSlot(_instant_, [[InitializedTemporalInstant]]). - 1. Let _timeZone_ be ? ToTemporalTimeZone(_temporalTimeZoneLike_). + 1. If Type(_item_) is Object, then + 1. Let _timeZoneProperty_ be ? Get(_item_, *"timeZone"*). + 1. If _timeZoneProperty_ is not *undefined*, then + 1. Set _item_ to _timeZoneProperty_. + 1. Let _timeZone_ be ? ToTemporalTimeZone(_item_). 1. Let _calendar_ be ? GetISO8601Calendar(). 1. Return ? CreateTemporalZonedDateTime(_instant_.[[Nanoseconds]], _timeZone_, _calendar_).