diff --git a/docs/cookbook/getLocalizedArrival.mjs b/docs/cookbook/getLocalizedArrival.mjs index e05a087af3..ef6fe5f65a 100644 --- a/docs/cookbook/getLocalizedArrival.mjs +++ b/docs/cookbook/getLocalizedArrival.mjs @@ -6,17 +6,19 @@ * @param {Temporal.Duration} flightTime - Duration of the flight * @param {Temporal.TimeZone} destinationTimeZone - Time zone in which the * flight's destination is located + * @param {Temporal.Calendar|string} calendar - Calendar system used for output * @returns {Temporal.DateTime} Local arrival time */ -function getLocalizedArrival(parseableDeparture, flightTime, destinationTimeZone) { +function getLocalizedArrival(parseableDeparture, flightTime, destinationTimeZone, calendar) { const departure = Temporal.Instant.from(parseableDeparture); const arrival = departure.add(flightTime); - return arrival.toDateTime(destinationTimeZone); + return arrival.toDateTime(destinationTimeZone, calendar); } const arrival = getLocalizedArrival( '2020-03-08T11:55:00+08:00[Asia/Hong_Kong]', Temporal.Duration.from({ minutes: 775 }), - 'America/Los_Angeles' + 'America/Los_Angeles', + 'iso8601' ); assert.equal(arrival.toString(), '2020-03-08T09:50'); diff --git a/docs/cookbook/meetingPlanner.js b/docs/cookbook/meetingPlanner.js index 153e440160..9bebe2029f 100644 --- a/docs/cookbook/meetingPlanner.js +++ b/docs/cookbook/meetingPlanner.js @@ -9,7 +9,8 @@ const timeZones = [ ]; // Start the table at midnight local time -const calendarNow = now.toDateTime(here); +const browserCalendar = new Intl.DateTimeFormat().resolvedOptions().calendar; +const calendarNow = now.toDateTime(here, browserCalendar); const startTime = calendarNow .with(Temporal.Time.from('00:00')) // midnight .toInstant(here); diff --git a/docs/instant.md b/docs/instant.md index be2bbf2aa4..44220d9fc2 100644 --- a/docs/instant.md +++ b/docs/instant.md @@ -225,13 +225,12 @@ Same as `getEpochSeconds()`, but with nanosecond (10−9 second) The value returned from this method is suitable to be passed to `new Temporal.Instant()`. -### instant.**toZonedDateTime**(_timeZone_: object | string, _calendar_?: object | string) : Temporal.ZonedDateTime +### instant.**toZonedDateTime**(_timeZone_: object | string, _calendar_: object | string) : Temporal.ZonedDateTime **Parameters:** - `timeZone` (object or string): A `Temporal.TimeZone` object, or an object implementing the [time zone protocol](./timezone.md#protocol), or a string description of the time zone; either its IANA name or UTC offset. -- `calendar` (optional object or string): A `Temporal.Calendar` object, or a plain object, or a calendar identifier. - The default is to use the ISO 8601 calendar. +- `calendar` (object or string): A `Temporal.Calendar` object, or a plain object, or a calendar identifier. **Returns:** a `Temporal.ZonedDateTime` object representing the calendar date, wall-clock time, time zone offset, and `timeZone`, according to the reckoning of `calendar`, at the exact time indicated by `instant`. @@ -240,28 +239,32 @@ A convenient list is also available [on Wikipedia](https://en.wikipedia.org/wiki For a list of calendar identifiers, see the documentation for [Intl.DateTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#Parameters). +If you only want to use the ISO 8601 calendar, use `toDateTimeISO()`. + Example usage: ```js -// Converting a specific exact time to a calendar date / wall-clock time -timestamp = Temporal.Instant.fromEpochSeconds(1553993100); -timestamp.toDateTime('Europe/Berlin'); // => 2019-03-31T01:45+02:00[Europe/Berlin] -timestamp.toDateTime('UTC'); // => 2019-03-31T00:45+00:00[UTC] -timestamp.toDateTime('-08:00'); // => 2019-03-30T16:45-08:00[-08:00] - -// What time was the Unix epoch (timestamp 0) in Bell Labs (Murray Hill, New Jersey, USA)? +// What time was the Unix epoch (timestamp 0) in Bell Labs (Murray Hill, New Jersey, USA) in the Gregorian calendar? epoch = Temporal.Instant.fromEpochSeconds(0); tz = Temporal.TimeZone.from('America/New_York'); -epoch.toZonedDateTime(tz); // => 1969-12-31T19:00-05:00[America/New_York] +epoch.toZonedDateTime(tz, 'gregory'); + // => 1969-12-31T19:00-05:00[America/New_York][c=gregory] + +// What time was the Unix epoch in Tokyo in the Japanese calendar? +tz = Temporal.TimeZone.from('Asia/Tokyo'); +cal = Temporal.Calendar.from('japanese'); +zdt = epoch.toZonedDateTime(tz, cal); + // => 1970-01-01T09:00+09:00[Asia/Tokyo][c=japanese] +console.log(zdt.year, zdt.era); + // => 45 showa ``` -### instant.**toDateTime**(_timeZone_: object | string, _calendar_?: object | string) : Temporal.DateTime +### instant.**toDateTime**(_timeZone_: object | string, _calendar_: object | string) : Temporal.DateTime **Parameters:** - `timeZone` (object or string): A `Temporal.TimeZone` object, or an object implementing the [time zone protocol](./timezone.md#protocol), or a string description of the time zone; either its IANA name or UTC offset. -- `calendar` (optional object or string): A `Temporal.Calendar` object, or a plain object, or a calendar identifier. - The default is to use the ISO 8601 calendar. +- `calendar` (object or string): A `Temporal.Calendar` object, or a plain object, or a calendar identifier. **Returns:** a `Temporal.DateTime` object indicating the calendar date and wall-clock time in `timeZone`, according to the reckoning of `calendar`, at the instant time indicated by `instant`. @@ -272,19 +275,24 @@ For a list of calendar identifiers, see the documentation for [Intl.DateTimeForm This method is one way to convert a `Temporal.Instant` to a `Temporal.DateTime`. +If you only want to use the ISO 8601 calendar, use `toDateTimeISO()`. + Example usage: ```js -// Converting a specific instant time to a calendar date / wall-clock time -timestamp = Temporal.Instant.fromEpochSeconds(1553993100); -timestamp.toDateTime('Europe/Berlin'); // => 2019-03-31T01:45 -timestamp.toDateTime('UTC'); // => 2019-03-31T00:45 -timestamp.toDateTime('-08:00'); // => 2019-03-30T16:45 - -// What time was the Unix epoch (timestamp 0) in Bell Labs (Murray Hill, New Jersey, USA)? +// What time was the Unix epoch (timestamp 0) in Bell Labs (Murray Hill, New Jersey, USA) in the Gregorian calendar? epoch = Temporal.Instant.fromEpochSeconds(0); tz = Temporal.TimeZone.from('America/New_York'); -epoch.toDateTime(tz); // => 1969-12-31T19:00 +epoch.toDateTime(tz, 'gregory'); + // => 1969-12-31T19:00[c=gregory] + +// What time was the Unix epoch in Tokyo in the Japanese calendar? +tz = Temporal.TimeZone.from('Asia/Tokyo'); +cal = Temporal.Calendar.from('japanese'); +dt = epoch.toDateTime(tz, cal); + // => 1970-01-01T09:00[c=japanese] +console.log(dt.year, dt.era); + // => 45 showa ``` ### instant.**add**(_duration_: object) : Temporal.Instant diff --git a/polyfill/lib/instant.mjs b/polyfill/lib/instant.mjs index d367d3c96d..96af0b8c44 100644 --- a/polyfill/lib/instant.mjs +++ b/polyfill/lib/instant.mjs @@ -235,7 +235,7 @@ export class Instant { valueOf() { throw new TypeError('use compare() or equals() to compare Temporal.Instant'); } - toDateTime(temporalTimeZoneLike, calendarLike = GetDefaultCalendar()) { + toDateTime(temporalTimeZoneLike, calendarLike) { if (!ES.IsTemporalInstant(this)) throw new TypeError('invalid receiver'); const timeZone = ES.ToTemporalTimeZone(temporalTimeZoneLike); const calendar = ES.ToTemporalCalendar(calendarLike); diff --git a/polyfill/test/Instant/prototype/toDateTime/length.js b/polyfill/test/Instant/prototype/toDateTime/length.js index c17a6ebe85..018a029fd3 100644 --- a/polyfill/test/Instant/prototype/toDateTime/length.js +++ b/polyfill/test/Instant/prototype/toDateTime/length.js @@ -16,7 +16,7 @@ includes: [propertyHelper.js] ---*/ verifyProperty(Temporal.Instant.prototype.toDateTime, "length", { - value: 1, + value: 2, writable: false, enumerable: false, configurable: true, diff --git a/polyfill/test/Instant/prototype/toDateTime/plain-custom-timezone.js b/polyfill/test/Instant/prototype/toDateTime/plain-custom-timezone.js index bef8171ddd..a5d96f8e37 100644 --- a/polyfill/test/Instant/prototype/toDateTime/plain-custom-timezone.js +++ b/polyfill/test/Instant/prototype/toDateTime/plain-custom-timezone.js @@ -14,6 +14,7 @@ const expected = [ const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789Z"); const dateTime = Temporal.DateTime.from("1963-07-02T12:00:00.987654321"); +const calendar = Temporal.Calendar.from("iso8601"); const timeZone = new Proxy({ getDateTimeFor(instantArg) { actual.push("call timeZone.getDateTimeFor"); @@ -31,7 +32,7 @@ const timeZone = new Proxy({ }, }); -const result = instant.toDateTime(timeZone); +const result = instant.toDateTime(timeZone, calendar); assert.sameValue(result, dateTime); assert.compareArray(actual, expected); diff --git a/polyfill/test/Instant/prototype/toDateTime/timezone-invalid-result.js b/polyfill/test/Instant/prototype/toDateTime/timezone-invalid-result.js index eaf277ec2c..bc0ee29d8c 100644 --- a/polyfill/test/Instant/prototype/toDateTime/timezone-invalid-result.js +++ b/polyfill/test/Instant/prototype/toDateTime/timezone-invalid-result.js @@ -6,6 +6,7 @@ esid: sec-temporal.instant.prototype.todatetime ---*/ const instant = Temporal.Instant.from("1975-02-02T14:25:36.123456789Z"); +const calendar = Temporal.Calendar.from("iso8601"); const invalidValues = [ undefined, @@ -22,14 +23,14 @@ const invalidValues = [ for (const dateTime of invalidValues) { const timeZone = { - getDateTimeFor(instantArg, calendar) { + getDateTimeFor(instantArg, calendarArg) { assert.sameValue(instantArg instanceof Temporal.Instant, true, "Instant"); assert.sameValue(instantArg, instant); - assert.sameValue(calendar instanceof Temporal.Calendar, true, "Calendar"); - assert.sameValue(calendar.id, "iso8601"); + assert.sameValue(calendarArg instanceof Temporal.Calendar, true, "Calendar"); + assert.sameValue(calendarArg, calendar); return dateTime; }, }; - assert.throws(TypeError, () => instant.toDateTime(timeZone)); + assert.throws(TypeError, () => instant.toDateTime(timeZone, calendar)); } diff --git a/polyfill/test/instant.mjs b/polyfill/test/instant.mjs index 558a1876a2..84b09635c6 100644 --- a/polyfill/test/instant.mjs +++ b/polyfill/test/instant.mjs @@ -33,6 +33,9 @@ describe('Instant', () => { it('Instant.prototype.round is a Function', () => { equal(typeof Instant.prototype.round, 'function'); }); + it('Instant.prototype.toDateTime is a Function', () => { + equal(typeof Instant.prototype.toDateTime, 'function'); + }); }); it('Instant.fromEpochSeconds is a Function', () => { equal(typeof Instant.fromEpochSeconds, 'function'); @@ -870,22 +873,24 @@ describe('Instant', () => { }); }); describe('Instant.toDateTime works', () => { - const iso = '1976-11-18T14:23:30.123456789Z'; - const abs = Instant.from(iso); - it('without parameter', () => { - throws(() => abs.toDateTime(), RangeError); + const inst = Instant.from('1976-11-18T14:23:30.123456789Z'); + it('throws without parameter', () => { + throws(() => inst.toDateTime(), RangeError); + }); + it('throws with only one parameter', () => { + throws(() => inst.toDateTime('Asia/Singapore')); }); it('time zone parameter UTC', () => { const tz = Temporal.TimeZone.from('UTC'); - const dt = abs.toDateTime(tz); - equal(abs.getEpochNanoseconds(), dt.toInstant(tz).getEpochNanoseconds()); - equal(`${dt}`, '1976-11-18T14:23:30.123456789'); + const dt = inst.toDateTime(tz, 'gregory'); + equal(inst.getEpochNanoseconds(), dt.toInstant(tz).getEpochNanoseconds()); + equal(`${dt}`, '1976-11-18T14:23:30.123456789[c=gregory]'); }); it('time zone parameter non-UTC', () => { const tz = Temporal.TimeZone.from('America/New_York'); - const dt = abs.toDateTime(tz); - equal(abs.getEpochNanoseconds(), dt.toInstant(tz).getEpochNanoseconds()); - equal(`${dt}`, '1976-11-18T09:23:30.123456789'); + const dt = inst.toDateTime(tz, 'gregory'); + equal(inst.getEpochNanoseconds(), dt.toInstant(tz).getEpochNanoseconds()); + equal(`${dt}`, '1976-11-18T09:23:30.123456789[c=gregory]'); }); }); }); diff --git a/polyfill/test/usertimezone.mjs b/polyfill/test/usertimezone.mjs index a2b26c310b..a831f81d20 100644 --- a/polyfill/test/usertimezone.mjs +++ b/polyfill/test/usertimezone.mjs @@ -52,7 +52,7 @@ describe('Userland time zone', () => { it('has offset string +00:00', () => equal(obj.getOffsetStringFor(abs), '+00:00')); it('converts to DateTime', () => { equal(`${obj.getDateTimeFor(abs)}`, '1970-01-01T00:00'); - equal(`${abs.toDateTime(obj)}`, '1970-01-01T00:00'); + equal(`${abs.toDateTime(obj, 'gregory')}`, '1970-01-01T00:00[c=gregory]'); }); it('converts to Instant', () => { equal(`${obj.getInstantFor(dt)}`, '1976-11-18T15:23:30.123456789Z'); @@ -103,7 +103,7 @@ describe('Userland time zone', () => { }); it('works for Instant.toDateTime', () => { const abs = Temporal.Instant.fromEpochSeconds(0); - equal(`${abs.toDateTime('Etc/Custom_UTC_Subclass')}`, '1970-01-01T00:00'); + equal(`${abs.toDateTime('Etc/Custom_UTC_Subclass', 'gregory')}`, '1970-01-01T00:00[c=gregory]'); }); it('works for DateTime.toInstant', () => { const dt = Temporal.DateTime.from('1970-01-01T00:00'); @@ -145,7 +145,7 @@ describe('Userland time zone', () => { equal(Temporal.TimeZone.prototype.getOffsetStringFor.call(obj, abs), '+00:00')); it('converts to DateTime', () => { equal(`${Temporal.TimeZone.prototype.getDateTimeFor.call(obj, abs)}`, '1970-01-01T00:00'); - equal(`${abs.toDateTime(obj)}`, '1970-01-01T00:00'); + equal(`${abs.toDateTime(obj, 'gregory')}`, '1970-01-01T00:00[c=gregory]'); }); it('converts to Instant', () => { equal(`${Temporal.TimeZone.prototype.getInstantFor.call(obj, dt)}`, '1976-11-18T15:23:30.123456789Z'); @@ -193,7 +193,7 @@ describe('Userland time zone', () => { }); it('works for Instant.toDateTime', () => { const abs = Temporal.Instant.fromEpochSeconds(0); - equal(`${abs.toDateTime('Etc/Custom_UTC_Protocol')}`, '1970-01-01T00:00'); + equal(`${abs.toDateTime('Etc/Custom_UTC_Protocol', 'gregory')}`, '1970-01-01T00:00[c=gregory]'); }); it('works for DateTime.toInstant', () => { const dt = Temporal.DateTime.from('1970-01-01T00:00'); diff --git a/spec/instant.html b/spec/instant.html index 293d968cc8..51e9a1d69a 100644 --- a/spec/instant.html +++ b/spec/instant.html @@ -429,7 +429,7 @@
The `toDateTime` method takes two arguments, _temporalTimeZoneLike_ and _calendar_. The following steps are taken: @@ -438,10 +438,7 @@