From 19a92481f9ec90435ae33b17fd97803b6e8caf67 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Fri, 30 Oct 2020 13:56:33 -0700 Subject: [PATCH] Add 'calendar' option to toString() methods The 'calendar' option takes values 'auto', 'always', and 'never', and controls whether to display the calendar in toString() for all the calendar types. See: #703 --- docs/date.md | 14 +++++++++++++- docs/datetime.md | 7 +++++++ docs/monthday.md | 12 ++++++++++++ docs/yearmonth.md | 12 ++++++++++++ docs/zoneddatetime.md | 9 ++++++++- polyfill/lib/date.mjs | 10 ++++++---- polyfill/lib/datetime.mjs | 7 ++++--- polyfill/lib/ecmascript.mjs | 8 ++++++-- polyfill/lib/monthday.mjs | 27 ++++++++++++++++++++------- polyfill/lib/yearmonth.mjs | 27 ++++++++++++++++++++------- polyfill/lib/zoneddatetime.mjs | 7 ++++--- polyfill/test/date.mjs | 20 ++++++++++++++++++++ polyfill/test/datetime.mjs | 19 +++++++++++++++++++ polyfill/test/monthday.mjs | 27 +++++++++++++++++++++++++++ polyfill/test/yearmonth.mjs | 27 +++++++++++++++++++++++++++ polyfill/test/zoneddatetime.mjs | 22 ++++++++++++++++++++++ spec/abstractops.html | 14 ++++++++++++++ spec/calendar.html | 6 ++++-- spec/date.html | 15 +++++++++------ spec/datetime.html | 11 ++++++----- spec/instant.html | 2 +- spec/monthday.html | 19 ++++++++++++------- spec/yearmonth.html | 20 ++++++++++++-------- spec/zoneddatetime.html | 13 +++++++------ 24 files changed, 292 insertions(+), 63 deletions(-) diff --git a/docs/date.md b/docs/date.md index 12f5616e64..fdd0ee8c62 100644 --- a/docs/date.md +++ b/docs/date.md @@ -555,13 +555,25 @@ date.equals(other); // => false date.equals(date); // => true ``` -### date.**toString**() : string +### date.**toString**(_options_?: object) : string + +**Parameters:** + +- `options` (optional object): An object with properties influencing the formatting. + The following options are recognized: + - `calendar` (string): Whether to show the calendar annotation in the return value. + Valid values are `'auto'`, `'always'`, and `'never'`. + The default is `'auto'`. **Returns:** a string in the ISO 8601 date format representing `date`. This method overrides the `Object.prototype.toString()` method and provides a convenient, unambiguous string representation of `date`. The string can be passed to `Temporal.Date.from()` to create a new `Temporal.Date` object. +Normally, a calendar annotation is shown when `date`'s calendar is not the ISO 8601 calendar. +By setting the `calendar` option to `'always'` or `'never'` this can be overridden to always or never show the annotation, respectively. +For more information on the calendar annotation, see [ISO string extensions](./iso-string-ext.md#calendar-systems). + Example usage: ```js diff --git a/docs/datetime.md b/docs/datetime.md index b3e100a912..b4c67dc58b 100644 --- a/docs/datetime.md +++ b/docs/datetime.md @@ -699,6 +699,9 @@ dt1.equals(dt1); // => true - `options` (optional object): An object with properties representing options for the operation. The following options are recognized: + - `calendar` (string): Whether to show the calendar annotation in the return value. + Valid values are `'auto'`, `'always'`, and `'never'`. + The default is `'auto'`. - `fractionalSecondDigits` (number or string): How many digits to print after the decimal point in the output string. Valid values are `'auto'`, 0, 1, 2, 3, 4, 5, 6, 7, 8, or 9. The default is `'auto'`. @@ -720,6 +723,10 @@ If no options are given, the default is `fractionalSecondDigits: 'auto'`, which The value is truncated to fit the requested precision, unless a different rounding mode is given with the `roundingMode` option, as in `Temporal.DateTime.round()`. Note that rounding may change the value of other units as well. +Normally, a calendar annotation is shown when `datetime`'s calendar is not the ISO 8601 calendar. +By setting the `calendar` option to `'always'` or `'never'` this can be overridden to always or never show the annotation, respectively. +For more information on the calendar annotation, see [ISO string extensions](./iso-string-ext.md#calendar-systems). + Example usage: ```js diff --git a/docs/monthday.md b/docs/monthday.md index 2a64254e8a..56f3afb0bf 100644 --- a/docs/monthday.md +++ b/docs/monthday.md @@ -181,11 +181,23 @@ dt1.equals(dt1) // => true ### monthDay.**toString**() : string +**Parameters:** + +- `options` (optional object): An object with properties influencing the formatting. + The following options are recognized: + - `calendar` (string): Whether to show the calendar annotation in the return value. + Valid values are `'auto'`, `'always'`, and `'never'`. + The default is `'auto'`. + **Returns:** a string in the ISO 8601 date format representing `monthDay`. This method overrides the `Object.prototype.toString()` method and provides a convenient, unambiguous string representation of `monthDay`. The string can be passed to `Temporal.MonthDay.from()` to create a new `Temporal.MonthDay` object. +Normally, a calendar annotation is shown when `monthDay`'s calendar is not the ISO 8601 calendar. +By setting the `calendar` option to `'always'` or `'never'` this can be overridden to always or never show the annotation, respectively. +For more information on the calendar annotation, see [ISO string extensions](./iso-string-ext.md#calendar-systems). + Example usage: ```js md = Temporal.MonthDay.from('08-24'); diff --git a/docs/yearmonth.md b/docs/yearmonth.md index 136f8ddf9b..8643e6b96e 100644 --- a/docs/yearmonth.md +++ b/docs/yearmonth.md @@ -451,11 +451,23 @@ ym.equals(ym); // => true ### yearMonth.**toString**() : string +**Parameters:** + +- `options` (optional object): An object with properties influencing the formatting. + The following options are recognized: + - `calendar` (string): Whether to show the calendar annotation in the return value. + Valid values are `'auto'`, `'always'`, and `'never'`. + The default is `'auto'`. + **Returns:** a string in the ISO 8601 date format representing `yearMonth`. This method overrides the `Object.prototype.toString()` method and provides a convenient, unambiguous string representation of `yearMonth`. The string can be passed to `Temporal.YearMonth.from()` to create a new `Temporal.YearMonth` object. +Normally, a calendar annotation is shown when `yearMonth`'s calendar is not the ISO 8601 calendar. +By setting the `calendar` option to `'always'` or `'never'` this can be overridden to always or never show the annotation, respectively. +For more information on the calendar annotation, see [ISO string extensions](./iso-string-ext.md#calendar-systems). + Example usage: ```js diff --git a/docs/zoneddatetime.md b/docs/zoneddatetime.md index e2e8f061ae..8fb648542d 100644 --- a/docs/zoneddatetime.md +++ b/docs/zoneddatetime.md @@ -1078,6 +1078,9 @@ zdt1.equals(zdt1); // => true - `options` (optional object): An object with properties influencing the formatting. The following options are recognized: + - `calendar` (string): Whether to show the calendar annotation in the return value. + Valid values are `'auto'`, `'always'`, and `'never'`. + The default is `'auto'`. - `fractionalSecondDigits` (number or string): How many digits to print after the decimal point in the output string. Valid values are `'auto'`, 0, 1, 2, 3, 4, 5, 6, 7, 8, or 9. The default is `'auto'`. @@ -1105,7 +1108,11 @@ If no options are given, the default is `fractionalSecondDigits: 'auto'`, which The value is truncated to fit the requested precision, unless a different rounding mode is given with the `roundingMode` option, as in `Temporal.DateTime.round()`. Note that rounding may change the value of other units as well. -The string format output by this method can be parsed by [`java.time.ZonedDateTime`](https://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html) as long as the calendar is `iso8601`. +Normally, a calendar annotation is shown when `zonedDateTime`'s calendar is not the ISO 8601 calendar. +By setting the `calendar` option to `'always'` or `'never'` this can be overridden to always or never show the annotation, respectively. +For more information on the calendar annotation, see [ISO string extensions](./iso-string-ext.md#calendar-systems). + +The string format output by this method can be parsed by [`java.time.ZonedDateTime`](https://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html) as long as the calendar annotation is not output. For more information on `Temporal`'s extensions to the ISO string format and the progress towards becoming a published standard, see [ISO standard extensions](./iso-string-ext.md). Example usage: diff --git a/polyfill/lib/date.mjs b/polyfill/lib/date.mjs index 5fd63b5bb2..3872c04aca 100644 --- a/polyfill/lib/date.mjs +++ b/polyfill/lib/date.mjs @@ -24,11 +24,11 @@ import { const ObjectAssign = Object.assign; -function TemporalDateToString(date) { +function TemporalDateToString(date, showCalendar = 'auto') { const year = ES.ISOYearString(GetSlot(date, ISO_YEAR)); const month = ES.ISODateTimePartString(GetSlot(date, ISO_MONTH)); const day = ES.ISODateTimePartString(GetSlot(date, ISO_DAY)); - const calendar = ES.FormatCalendarAnnotation(GetSlot(date, CALENDAR)); + const calendar = ES.FormatCalendarAnnotation(GetSlot(date, CALENDAR), showCalendar); return `${year}-${month}-${day}${calendar}`; } @@ -290,9 +290,11 @@ export class Date { } return ES.CalendarEquals(this, other); } - toString() { + toString(options = undefined) { if (!ES.IsTemporalDate(this)) throw new TypeError('invalid receiver'); - return TemporalDateToString(this); + options = ES.NormalizeOptionsObject(options); + const showCalendar = ES.ToShowCalendarOption(options); + return TemporalDateToString(this, showCalendar); } toJSON() { if (!ES.IsTemporalDate(this)) throw new TypeError('invalid receiver'); diff --git a/polyfill/lib/datetime.mjs b/polyfill/lib/datetime.mjs index 2a998cf494..fd0411111a 100644 --- a/polyfill/lib/datetime.mjs +++ b/polyfill/lib/datetime.mjs @@ -24,7 +24,7 @@ import { const ObjectAssign = Object.assign; -function DateTimeToString(dateTime, precision, options = undefined) { +function DateTimeToString(dateTime, precision, showCalendar = 'auto', options = undefined) { let year = GetSlot(dateTime, ISO_YEAR); let month = GetSlot(dateTime, ISO_MONTH); let day = GetSlot(dateTime, ISO_DAY); @@ -59,7 +59,7 @@ function DateTimeToString(dateTime, precision, options = undefined) { hour = ES.ISODateTimePartString(hour); minute = ES.ISODateTimePartString(minute); const seconds = ES.FormatSecondsStringPart(second, millisecond, microsecond, nanosecond, precision); - const calendar = ES.FormatCalendarAnnotation(GetSlot(dateTime, CALENDAR)); + const calendar = ES.FormatCalendarAnnotation(GetSlot(dateTime, CALENDAR), showCalendar); return `${year}-${month}-${day}T${hour}:${minute}${seconds}${calendar}`; } @@ -699,8 +699,9 @@ export class DateTime { if (!ES.IsTemporalDateTime(this)) throw new TypeError('invalid receiver'); options = ES.NormalizeOptionsObject(options); const { precision, unit, increment } = ES.ToSecondsStringPrecision(options); + const showCalendar = ES.ToShowCalendarOption(options); const roundingMode = ES.ToTemporalRoundingMode(options, 'trunc'); - return DateTimeToString(this, precision, { unit, increment, roundingMode }); + return DateTimeToString(this, precision, showCalendar, { unit, increment, roundingMode }); } toJSON() { if (!ES.IsTemporalDateTime(this)) throw new TypeError('invalid receiver'); diff --git a/polyfill/lib/ecmascript.mjs b/polyfill/lib/ecmascript.mjs index 2c859b0795..ce44b29f8a 100644 --- a/polyfill/lib/ecmascript.mjs +++ b/polyfill/lib/ecmascript.mjs @@ -123,9 +123,10 @@ export const ES = ObjectAssign({}, ES2020, { } return result; }, - FormatCalendarAnnotation: (calendar) => { + FormatCalendarAnnotation: (calendar, showCalendar) => { + if (showCalendar === 'never') return ''; const id = ES.CalendarToString(calendar); - if (id === 'iso8601') return ''; + if (showCalendar === 'auto' && id === 'iso8601') return ''; return `[c=${id}]`; }, ParseISODateTime: (isoString, { zoneRequired }) => { @@ -468,6 +469,9 @@ export const ES = ObjectAssign({}, ES2020, { ToTemporalOffset: (options, fallback) => { return ES.GetOption(options, 'offset', ['prefer', 'use', 'ignore', 'reject'], fallback); }, + ToShowCalendarOption: (options) => { + return ES.GetOption(options, 'calendar', ['auto', 'always', 'never'], 'auto'); + }, ToTemporalRoundingIncrement: (options, dividend, inclusive) => { let maximum = Infinity; if (dividend !== undefined) maximum = dividend; diff --git a/polyfill/lib/monthday.mjs b/polyfill/lib/monthday.mjs index ff56bd1dcf..962c84c0f5 100644 --- a/polyfill/lib/monthday.mjs +++ b/polyfill/lib/monthday.mjs @@ -4,18 +4,29 @@ import { GetISO8601Calendar } from './calendar.mjs'; import { ES } from './ecmascript.mjs'; import { DateTimeFormat } from './intl.mjs'; import { GetIntrinsic, MakeIntrinsicClass } from './intrinsicclass.mjs'; -import { ISO_MONTH, ISO_DAY, ISO_YEAR, CALENDAR, MONTH_DAY_BRAND, CreateSlots, GetSlot, SetSlot } from './slots.mjs'; +import { + ISO_MONTH, + ISO_DAY, + ISO_YEAR, + CALENDAR, + CALENDAR_ID, + MONTH_DAY_BRAND, + CreateSlots, + GetSlot, + SetSlot +} from './slots.mjs'; const ObjectAssign = Object.assign; -function MonthDayToString(monthDay) { +function MonthDayToString(monthDay, showCalendar = 'auto') { const month = ES.ISODateTimePartString(GetSlot(monthDay, ISO_MONTH)); const day = ES.ISODateTimePartString(GetSlot(monthDay, ISO_DAY)); let resultString = `${month}-${day}`; - const calendar = ES.FormatCalendarAnnotation(GetSlot(monthDay, CALENDAR)); - if (calendar) { + const calendar = GetSlot(monthDay, CALENDAR); + const calendarString = ES.FormatCalendarAnnotation(GetSlot(monthDay, CALENDAR), showCalendar); + if (calendarString || !ES.IsTemporalCalendar(calendar) || GetSlot(calendar, CALENDAR_ID) !== 'iso8601') { const year = ES.ISOYearString(GetSlot(monthDay, ISO_YEAR)); - resultString = `${year}-${resultString}${calendar}`; + resultString = `${year}-${resultString}${calendarString}`; } return resultString; } @@ -87,9 +98,11 @@ export class MonthDay { } return ES.CalendarEquals(this, other); } - toString() { + toString(options = undefined) { if (!ES.IsTemporalMonthDay(this)) throw new TypeError('invalid receiver'); - return MonthDayToString(this); + options = ES.NormalizeOptionsObject(options); + const showCalendar = ES.ToShowCalendarOption(options); + return MonthDayToString(this, showCalendar); } toJSON() { if (!ES.IsTemporalMonthDay(this)) throw new TypeError('invalid receiver'); diff --git a/polyfill/lib/yearmonth.mjs b/polyfill/lib/yearmonth.mjs index 80f3c46ca0..c9fd896243 100644 --- a/polyfill/lib/yearmonth.mjs +++ b/polyfill/lib/yearmonth.mjs @@ -4,18 +4,29 @@ import { GetISO8601Calendar } from './calendar.mjs'; import { ES } from './ecmascript.mjs'; import { DateTimeFormat } from './intl.mjs'; import { GetIntrinsic, MakeIntrinsicClass } from './intrinsicclass.mjs'; -import { ISO_YEAR, ISO_MONTH, ISO_DAY, YEAR_MONTH_BRAND, CALENDAR, CreateSlots, GetSlot, SetSlot } from './slots.mjs'; +import { + ISO_YEAR, + ISO_MONTH, + ISO_DAY, + YEAR_MONTH_BRAND, + CALENDAR, + CALENDAR_ID, + CreateSlots, + GetSlot, + SetSlot +} from './slots.mjs'; const ObjectAssign = Object.assign; -function YearMonthToString(yearMonth) { +function YearMonthToString(yearMonth, showCalendar = 'auto') { const year = ES.ISOYearString(GetSlot(yearMonth, ISO_YEAR)); const month = ES.ISODateTimePartString(GetSlot(yearMonth, ISO_MONTH)); let resultString = `${year}-${month}`; - const calendar = ES.FormatCalendarAnnotation(GetSlot(yearMonth, CALENDAR)); - if (calendar) { + const calendar = GetSlot(yearMonth, CALENDAR); + const calendarString = ES.FormatCalendarAnnotation(calendar, showCalendar); + if (calendarString || !ES.IsTemporalCalendar(calendar) || GetSlot(calendar, CALENDAR_ID) !== 'iso8601') { const day = ES.ISODateTimePartString(GetSlot(yearMonth, ISO_DAY)); - resultString = `${resultString}-${day}${calendar}`; + resultString = `${resultString}-${day}${calendarString}`; } return resultString; } @@ -288,9 +299,11 @@ export class YearMonth { } return ES.CalendarEquals(this, other); } - toString() { + toString(options = undefined) { if (!ES.IsTemporalYearMonth(this)) throw new TypeError('invalid receiver'); - return YearMonthToString(this); + options = ES.NormalizeOptionsObject(options); + const showCalendar = ES.ToShowCalendarOption(options); + return YearMonthToString(this, showCalendar); } toJSON() { if (!ES.IsTemporalYearMonth(this)) throw new TypeError('invalid receiver'); diff --git a/polyfill/lib/zoneddatetime.mjs b/polyfill/lib/zoneddatetime.mjs index ce37780696..bab7a6d247 100644 --- a/polyfill/lib/zoneddatetime.mjs +++ b/polyfill/lib/zoneddatetime.mjs @@ -311,7 +311,8 @@ export class ZonedDateTime { options = ES.NormalizeOptionsObject(options); const { precision, unit, increment } = ES.ToSecondsStringPrecision(options); const roundingMode = ES.ToTemporalRoundingMode(options, 'trunc'); - return zonedDateTimeToString(this, precision, { unit, increment, roundingMode }); + const showCalendar = ES.ToShowCalendarOption(options); + return zonedDateTimeToString(this, precision, showCalendar, { unit, increment, roundingMode }); } toLocaleString(locales = undefined, options = undefined) { if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver'); @@ -416,7 +417,7 @@ function dateTime(zdt) { return ES.GetTemporalDateTimeFor(GetSlot(zdt, TIME_ZONE), GetSlot(zdt, INSTANT), GetSlot(zdt, CALENDAR)); } -function zonedDateTimeToString(zdt, precision, options = undefined) { +function zonedDateTimeToString(zdt, precision, showCalendar = 'auto', options = undefined) { const dt = dateTime(zdt); let year = GetSlot(dt, ISO_YEAR); let month = GetSlot(dt, ISO_MONTH); @@ -455,6 +456,6 @@ function zonedDateTimeToString(zdt, precision, options = undefined) { const tz = GetSlot(zdt, TIME_ZONE); const offset = ES.GetOffsetStringFor(tz, GetSlot(zdt, INSTANT)); const zone = ES.TimeZoneToString(tz); - const calendar = ES.FormatCalendarAnnotation(GetSlot(zdt, CALENDAR)); + const calendar = ES.FormatCalendarAnnotation(GetSlot(zdt, CALENDAR), showCalendar); return `${year}-${month}-${day}T${hour}:${minute}${seconds}${offset}[${zone}]${calendar}`; } diff --git a/polyfill/test/date.mjs b/polyfill/test/date.mjs index bc499b55fe..b750e7765d 100644 --- a/polyfill/test/date.mjs +++ b/polyfill/test/date.mjs @@ -852,6 +852,26 @@ describe('Date', () => { it('new Date(1914, 2, 23).toString()', () => { equal(new Date(1914, 2, 23).toString(), '1914-02-23'); }); + const d = new Date(1976, 11, 18); + it('shows only non-ISO calendar if calendar = auto', () => { + equal(d.toString({ calendar: 'auto' }), '1976-11-18'); + equal(d.withCalendar('gregory').toString({ calendar: 'auto' }), '1976-11-18[c=gregory]'); + }); + it('shows ISO calendar if calendar = always', () => { + equal(d.toString({ calendar: 'always' }), '1976-11-18[c=iso8601]'); + }); + it('omits non-ISO calendar if calendar = never', () => { + equal(d.withCalendar('gregory').toString({ calendar: 'never' }), '1976-11-18'); + }); + it('default is calendar = auto', () => { + equal(d.toString(), '1976-11-18'); + equal(d.withCalendar('gregory').toString(), '1976-11-18[c=gregory]'); + }); + it('throws on invalid calendar', () => { + ['ALWAYS', 'sometimes', false, 3, null].forEach((calendar) => { + throws(() => d.toString({ calendar }), RangeError); + }); + }); }); describe('Date.from() works', () => { it('Date.from("1976-11-18")', () => { diff --git a/polyfill/test/datetime.mjs b/polyfill/test/datetime.mjs index 31ded28273..79e5e15707 100644 --- a/polyfill/test/datetime.mjs +++ b/polyfill/test/datetime.mjs @@ -1710,6 +1710,25 @@ describe('DateTime', () => { equal(dt2.toString(), '1976-11-18T15:23:30'); equal(dt3.toString(), '1976-11-18T15:23:30.1234'); }); + it('shows only non-ISO calendar if calendar = auto', () => { + equal(dt1.toString({ calendar: 'auto' }), '1976-11-18T15:23:00'); + equal(dt1.withCalendar('gregory').toString({ calendar: 'auto' }), '1976-11-18T15:23:00[c=gregory]'); + }); + it('shows ISO calendar if calendar = always', () => { + equal(dt1.toString({ calendar: 'always' }), '1976-11-18T15:23:00[c=iso8601]'); + }); + it('omits non-ISO calendar if calendar = never', () => { + equal(dt1.withCalendar('gregory').toString({ calendar: 'never' }), '1976-11-18T15:23:00'); + }); + it('default is calendar = auto', () => { + equal(dt1.toString(), '1976-11-18T15:23:00'); + equal(dt1.withCalendar('gregory').toString(), '1976-11-18T15:23:00[c=gregory]'); + }); + it('throws on invalid calendar', () => { + ['ALWAYS', 'sometimes', false, 3, null].forEach((calendar) => { + throws(() => dt1.toString({ calendar }), RangeError); + }); + }); it('truncates to minute', () => { [dt1, dt2, dt3].forEach((dt) => equal(dt.toString({ smallestUnit: 'minute' }), '1976-11-18T15:23')); }); diff --git a/polyfill/test/monthday.mjs b/polyfill/test/monthday.mjs index 64acb6131b..ea71ad97cc 100644 --- a/polyfill/test/monthday.mjs +++ b/polyfill/test/monthday.mjs @@ -23,6 +23,9 @@ describe('MonthDay', () => { it('MonthDay.prototype.equals is a Function', () => { equal(typeof MonthDay.prototype.equals, 'function'); }); + it('MonthDay.prototype.toString is a Function', () => { + equal(typeof MonthDay.prototype.toString, 'function'); + }); it('MonthDay.prototype.getFields is a Function', () => { equal(typeof MonthDay.prototype.getFields, 'function'); }); @@ -212,6 +215,30 @@ describe('MonthDay', () => { throws(() => leapDay.toDateInYear(2019, { overflow: 'reject' })); }); }); + describe('MonthDay.toString()', () => { + const md1 = MonthDay.from('11-18'); + const md2 = MonthDay.from({ month: 11, day: 18, calendar: 'gregory' }); + it('shows only non-ISO calendar if calendar = auto', () => { + equal(md1.toString({ calendar: 'auto' }), '11-18'); + equal(md2.toString({ calendar: 'auto' }), '1972-11-18[c=gregory]'); + }); + it('shows ISO calendar if calendar = always', () => { + equal(md1.toString({ calendar: 'always' }), '1972-11-18[c=iso8601]'); + }); + it('omits non-ISO calendar, but not year, if calendar = never', () => { + equal(md1.toString({ calendar: 'never' }), '11-18'); + equal(md2.toString({ calendar: 'never' }), '1972-11-18'); + }); + it('default is calendar = auto', () => { + equal(md1.toString(), '11-18'); + equal(md2.toString(), '1972-11-18[c=gregory]'); + }); + it('throws on invalid calendar', () => { + ['ALWAYS', 'sometimes', false, 3, null].forEach((calendar) => { + throws(() => md1.toString({ calendar }), RangeError); + }); + }); + }); describe('monthDay.getFields() works', () => { const calendar = Temporal.Calendar.from('iso8601'); const md1 = MonthDay.from({ month: 11, day: 18, calendar }); diff --git a/polyfill/test/yearmonth.mjs b/polyfill/test/yearmonth.mjs index 6d656319b8..f67852cfa3 100644 --- a/polyfill/test/yearmonth.mjs +++ b/polyfill/test/yearmonth.mjs @@ -29,6 +29,9 @@ describe('YearMonth', () => { it('YearMonth.prototype.equals is a Function', () => { equal(typeof YearMonth.prototype.equals, 'function'); }); + it('YearMonth.prototype.toString is a Function', () => { + equal(typeof YearMonth.prototype.toString, 'function'); + }); it('YearMonth.prototype.getFields is a Function', () => { equal(typeof YearMonth.prototype.getFields, 'function'); }); @@ -697,6 +700,30 @@ describe('YearMonth', () => { ); }); }); + describe('YearMonth.toString()', () => { + const ym1 = YearMonth.from('1976-11'); + const ym2 = YearMonth.from({ year: 1976, month: 11, calendar: 'gregory' }); + it('shows only non-ISO calendar if calendar = auto', () => { + equal(ym1.toString({ calendar: 'auto' }), '1976-11'); + equal(ym2.toString({ calendar: 'auto' }), '1976-11-01[c=gregory]'); + }); + it('shows ISO calendar if calendar = always', () => { + equal(ym1.toString({ calendar: 'always' }), '1976-11-01[c=iso8601]'); + }); + it('omits non-ISO calendar, but not day, if calendar = never', () => { + equal(ym1.toString({ calendar: 'never' }), '1976-11'); + equal(ym2.toString({ calendar: 'never' }), '1976-11-01'); + }); + it('default is calendar = auto', () => { + equal(ym1.toString(), '1976-11'); + equal(ym2.toString(), '1976-11-01[c=gregory]'); + }); + it('throws on invalid calendar', () => { + ['ALWAYS', 'sometimes', false, 3, null].forEach((calendar) => { + throws(() => ym1.toString({ calendar }), RangeError); + }); + }); + }); describe('yearMonth.getFields() works', () => { const calendar = Temporal.Calendar.from('iso8601'); const ym1 = YearMonth.from({ year: 1976, month: 11, calendar }); diff --git a/polyfill/test/zoneddatetime.mjs b/polyfill/test/zoneddatetime.mjs index e325c4a519..177fe5c3d4 100644 --- a/polyfill/test/zoneddatetime.mjs +++ b/polyfill/test/zoneddatetime.mjs @@ -344,6 +344,28 @@ describe('ZonedDateTime', () => { equal(zdt2.toString(), '1976-11-18T15:23:30+01:00[Europe/Vienna]'); equal(zdt3.toString(), '1976-11-18T15:23:30.1234+01:00[Europe/Vienna]'); }); + it('shows only non-ISO calendar if calendar = auto', () => { + equal(zdt1.toString({ calendar: 'auto' }), '1976-11-18T15:23:00+01:00[Europe/Vienna]'); + equal( + zdt1.withCalendar('gregory').toString({ calendar: 'auto' }), + '1976-11-18T15:23:00+01:00[Europe/Vienna][c=gregory]' + ); + }); + it('shows ISO calendar if calendar = always', () => { + equal(zdt1.toString({ calendar: 'always' }), '1976-11-18T15:23:00+01:00[Europe/Vienna][c=iso8601]'); + }); + it('omits non-ISO calendar if calendar = never', () => { + equal(zdt1.withCalendar('gregory').toString({ calendar: 'never' }), '1976-11-18T15:23:00+01:00[Europe/Vienna]'); + }); + it('default is calendar = auto', () => { + equal(zdt1.toString(), '1976-11-18T15:23:00+01:00[Europe/Vienna]'); + equal(zdt1.withCalendar('gregory').toString(), '1976-11-18T15:23:00+01:00[Europe/Vienna][c=gregory]'); + }); + it('throws on invalid calendar', () => { + ['ALWAYS', 'sometimes', false, 3, null].forEach((calendar) => { + throws(() => zdt1.toString({ calendar }), RangeError); + }); + }); it('truncates to minute', () => { [zdt1, zdt2, zdt3].forEach((zdt) => equal(zdt.toString({ smallestUnit: 'minute' }), '1976-11-18T15:23+01:00[Europe/Vienna]') diff --git a/spec/abstractops.html b/spec/abstractops.html index 7234663aa6..21e91fbd66 100644 --- a/spec/abstractops.html +++ b/spec/abstractops.html @@ -173,6 +173,20 @@

ToTemporalOffset ( _normalizedOptions_, _fallback_ )

+ +

ToShowCalendarOption ( _normalizedOptions_ )

+

+ The abstract operation ToShowCalendarOption extracts the value of the property named *"calendar"* from _normalizedOptions_ and makes sure it is a valid value for the option. +

+ + This property is used in `toString` methods in Temporal. + It is different from the `calendar` property passed to `from` methods. + + + 1. Return ? GetOption(_normalizedOptions_, *"calendar"*, *"string"*, « *"auto"*, *"always"*, *"never"* », *"auto"*). + +
+

ToTemporalRoundingIncrement ( _normalizedOptions_, _dividend_, _inclusive_ )

diff --git a/spec/calendar.html b/spec/calendar.html index 5ad238fed7..8e0a9aa416 100644 --- a/spec/calendar.html +++ b/spec/calendar.html @@ -90,10 +90,12 @@

CalendarFrom ( _identifier_ )

-

FormatCalendarAnnotation ( _calendar_ )

+

FormatCalendarAnnotation ( _calendar_, _showCalendar_ )

+ 1. Assert: _showCalendar_ is *"auto"*, *"always"*, or *"never"*. + 1. If _showCalendar_ is *"never"*, return the empty String. 1. Let _id_ be ? CalendarToString(_calendar_). - 1. If _id_ is *"iso8601"*, return the empty String. + 1. If _showCalendar_ is *"auto"* and _id_ is *"iso8601"*, return the empty String. 1. Return the string-concatenation of *"[c="*, _id_, and *"]"*.
diff --git a/spec/date.html b/spec/date.html index 4f589d1292..866557351b 100644 --- a/spec/date.html +++ b/spec/date.html @@ -545,14 +545,17 @@

Temporal.Date.prototype.toZonedDateTime ( _timeZoneLike_ [ , _temporalTime_ -

Temporal.Date.prototype.toString ( )

+

Temporal.Date.prototype.toString ( [ _options_ ] )

+ The `toString` method takes one argument _options_. The following steps are taken:

1. Let _temporalDate_ be the *this* value. 1. Perform ? RequireInternalSlot(_temporalDate_, [[InitializedTemporalDate]]). - 1. Return ? TemporalDateToString(_temporalDate_). + 1. Set _options_ to ? NormalizeOptionsObject(_options_). + 1. Let _showCalendar_ be ? ToShowCalendarOption(_options_). + 1. Return ? TemporalDateToString(_temporalDate_, _showCalendar_).
@@ -566,7 +569,7 @@

Temporal.Date.prototype.toLocaleString ( [ _locales_ [ , _options_ ] ] )

@@ -580,7 +583,7 @@

Temporal.Date.prototype.toJSON ( )

1. Let _temporalDate_ be the *this* value. 1. Perform ? RequireInternalSlot(_temporalDate_, [[InitializedTemporalDate]]). - 1. Return ? TemporalDateToString(_temporalDate_). + 1. Return ? TemporalDateToString(_temporalDate_, *"auto"*). @@ -956,14 +959,14 @@

PadYear ( _y_ )

-

TemporalDateToString ( _temporalDate_ )

+

TemporalDateToString ( _temporalDate_, _showCalendar_ )

1. Assert: Type(_temporalDate_) is Object. 1. Assert: _temporalDate_ has an [[InitializedTemporalDate]] internal slot. 1. Let _year_ be ! PadYear(_temporalDate_.[[ISOYear]]). 1. Let _month_ be _temporalDate_.[[ISOMonth]] formatted as a two-digit decimal number, padded to the left with a zero if necessary. 1. Let _day_ be _temporalDate_.[[ISODay]] formatted as a two-digit decimal number, padded to the left with a zero if necessary. - 1. Let _calendar_ be ? FormatCalendarAnnotation(_temporalDate_.[[Calendar]]). + 1. Let _calendar_ be ? FormatCalendarAnnotation(_temporalDate_.[[Calendar]], _showCalendar_). 1. Return the string-concatenation of _year_, the code unit 0x002D (HYPHEN-MINUS), _month_, the code unit 0x002D (HYPHEN-MINUS), _day_, and _calendar_.
diff --git a/spec/datetime.html b/spec/datetime.html index 422f59c184..28f3878f78 100644 --- a/spec/datetime.html +++ b/spec/datetime.html @@ -598,8 +598,9 @@

Temporal.DateTime.prototype.toString ( [ _options_ ] )

1. Set _options_ to ? NormalizeOptionsObject(_options_). 1. Let _precision_ be ? ToSecondsStringPrecision(_options_). 1. Let _roundingMode_ be ? ToTemporalRoundingMode(_options_, *"trunc"*). + 1. Let _showCalendar_ be ? ToShowCalendarOption(_options_). 1. Let _result_ be ? RoundDateTime(_dateTime_.[[ISOYear]], _dateTime_.[[ISOMonth]], _dateTime_.[[ISODay]], _dateTime_.[[Hour]], _dateTime_.[[Minute]], _dateTime_.[[Second]], _dateTime_.[[Millisecond]], _dateTime_.[[Microsecond]], _dateTime_.[[Nanosecond]], _precision_.[[Increment]], _precision_.[[Unit]], _roundingMode_). - 1. Return ? TemporalDateTimeToString(_result_.[[Year]], _result_.[[Month]], _result_.[[Day]], _result_.[[Hour]], _result_.[[Minute]], _result_.[[Second]], _result_.[[Millisecond]], _result_.[[Microsecond]], _result_.[[Nanosecond]], _dateTime_.[[Calendar]], _precision_.[[Precision]]). + 1. Return ? TemporalDateTimeToString(_result_.[[Year]], _result_.[[Month]], _result_.[[Day]], _result_.[[Hour]], _result_.[[Minute]], _result_.[[Second]], _result_.[[Millisecond]], _result_.[[Microsecond]], _result_.[[Nanosecond]], _dateTime_.[[Calendar]], _precision_.[[Precision]], _showCalendar_). @@ -613,7 +614,7 @@

Temporal.DateTime.prototype.toLocaleString ( [ _locales_ [ , _options_ ] ] ) 1. Let _dateTime_ be the *this* value. 1. Perform ? RequireInternalSlot(_dateTime_, [[InitializedTemporalDateTime]]). 1. If the implementation does not include the ECMA-402 Internationalization API, then - 1. Return ? TemporalDateTimeToString(_dateTime_.[[ISOYear]], _dateTime_.[[ISOMonth]], _dateTime_.[[ISODay]], _dateTime_.[[Hour]], _dateTime_.[[Minute]], _dateTime_.[[Second]], _dateTime_.[[Millisecond]], _dateTime_.[[Microsecond]], _dateTime_.[[Nanosecond]], _dateTime_.[[Calendar]], *"auto"*). + 1. Return ? TemporalDateTimeToString(_dateTime_.[[ISOYear]], _dateTime_.[[ISOMonth]], _dateTime_.[[ISODay]], _dateTime_.[[Hour]], _dateTime_.[[Minute]], _dateTime_.[[Second]], _dateTime_.[[Millisecond]], _dateTime_.[[Microsecond]], _dateTime_.[[Nanosecond]], _dateTime_.[[Calendar]], *"auto"*, *"auto"*). 1. Let _dateFormat_ be ? Construct(%DateTimeFormat%, « _locales_, _options_ »). 1. Return ? FormatDateTime(_dateFormat_, _dateTime_). @@ -627,7 +628,7 @@

Temporal.DateTime.prototype.toJSON ( )

1. Let _dateTime_ be the *this* value. 1. Perform ? RequireInternalSlot(_dateTime_, [[InitializedTemporalDateTime]]). - 1. Return ? TemporalDateTimeToString(_dateTime_.[[ISOYear]], _dateTime_.[[ISOMonth]], _dateTime_.[[ISODay]], _dateTime_.[[Hour]], _dateTime_.[[Minute]], _dateTime_.[[Second]], _dateTime_.[[Millisecond]], _dateTime_.[[Microsecond]], _dateTime_.[[Nanosecond]], _dateTime_.[[Calendar]], *"auto"*). + 1. Return ? TemporalDateTimeToString(_dateTime_.[[ISOYear]], _dateTime_.[[ISOMonth]], _dateTime_.[[ISODay]], _dateTime_.[[Hour]], _dateTime_.[[Minute]], _dateTime_.[[Second]], _dateTime_.[[Millisecond]], _dateTime_.[[Microsecond]], _dateTime_.[[Nanosecond]], _dateTime_.[[Calendar]], *"auto"*, *"auto"*). @@ -1120,7 +1121,7 @@

ToTemporalDateTimeFields ( _temporalDateTimeLike_, _fieldNames_ )

-

TemporalDateTimeToString ( _isoYear_, _isoMonth_, _isoDay_, _hour_, _minute_, _second_, _millisecond_, _microsecond_, _nanosecond_, _calendar_, _precision_ )

+

TemporalDateTimeToString ( _isoYear_, _isoMonth_, _isoDay_, _hour_, _minute_, _second_, _millisecond_, _microsecond_, _nanosecond_, _calendar_, _precision_, _showCalendar_ )

1. Let _year_ be ! PadYear(_isoYear_). 1. Let _month_ be _isoMonth_ formatted as a two-digit decimal number, padded to the left with a zero if necessary. @@ -1128,7 +1129,7 @@

TemporalDateTimeToString ( _isoYear_, _isoMonth_, _isoDay_, _hour_, _minute_ 1. Let _hour_ be _hour_ formatted as a two-digit decimal number, padded to the left with a zero if necessary. 1. Let _minute_ be _minute_ formatted as a two-digit decimal number, padded to the left with a zero if necessary. 1. Let _seconds_ be ! FormatSecondsStringPart(_second_, _millisecond_, _microsecond_, _nanosecond_, _precision_). - 1. Let _calendar_ be ? FormatCalendarAnnotation(_dateTime_.[[Calendar]]). + 1. Let _calendar_ be ? FormatCalendarAnnotation(_dateTime_.[[Calendar]], _showCalendar_). 1. Return the string-concatenation of _year_, the code unit 0x002D (HYPHEN-MINUS), _month_, the code unit 0x002D (HYPHEN-MINUS), _day_, 0x0054 (LATIN CAPITAL LETTER T), _hour_, the code unit 0x003A (COLON), _minute_, _seconds_, and _calendar_. diff --git a/spec/instant.html b/spec/instant.html index f51c2102d1..72d7c32b55 100644 --- a/spec/instant.html +++ b/spec/instant.html @@ -691,7 +691,7 @@

TemporalInstantToString ( _instant_, _timeZone_, _calendar_, _precision_ ) diff --git a/spec/monthday.html b/spec/monthday.html index fa7b2f428b..20b618b7d4 100644 --- a/spec/monthday.html +++ b/spec/monthday.html @@ -170,14 +170,17 @@

Temporal.MonthDay.prototype.equals ( _other_ )

-

Temporal.MonthDay.prototype.toString ( )

+

Temporal.MonthDay.prototype.toString ( [ _options_ ] )

+ The `toString` method takes one argument _options_. The following steps are taken:

1. Let _monthDay_ be the *this* value. 1. Perform ? RequireInternalSlot(_monthDay_, [[InitializedTemporalMonthDay]]). - 1. Return ! TemporalMonthDayToString(_monthDay_). + 1. Set _options_ to ? NormalizeOptionsObject(_options_). + 1. Let _showCalendar_ be ? ToShowCalendarOption(_options_). + 1. Return ! TemporalMonthDayToString(_monthDay_, _showCalendar_).
@@ -191,7 +194,7 @@

Temporal.MonthDay.prototype.toLocaleString ( [ _locales_ [ , _options_ ] ] ) 1. Let _monthDay_ be the *this* value. 1. Perform ? RequireInternalSlot(_monthDay_, [[InitializedTemporalMonthDay]]). 1. If the implementation does not include the ECMA-402 Internationalization API, then - 1. Return ! TemporalMonthDayToString(_monthDay_). + 1. Return ! TemporalMonthDayToString(_monthDay_, *"auto"*). 1. Let _dateFormat_ be ? Construct(%DateTimeFormat%, « _locales_, _options_ »). 1. Return ? FormatDateTime(_dateFormat_, _monthDay_). @@ -205,7 +208,7 @@

Temporal.MonthDay.prototype.toJSON ( )

1. Let _monthDay_ be the *this* value. 1. Perform ? RequireInternalSlot(_monthDay_, [[InitializedTemporalMonthDay]]). - 1. Return ! TemporalMonthDayToString(_monthDay_). + 1. Return ! TemporalMonthDayToString(_monthDay_, *"auto"*). @@ -507,16 +510,18 @@

ToTemporalMonthDayFields ( _temporalMonthDayLike_, _fieldNames_ )

-

TemporalMonthDayToString ( _monthDay_ )

+

TemporalMonthDayToString ( _monthDay_, _showCalendar_ )

1. Assert: Type(_monthDay_) is Object. 1. Assert: _monthDay_ has an [[InitializedTemporalMonthDay]] internal slot. 1. Let _month_ be _monthDay_.[[ISOMonth]] formatted as a two-digit decimal number, padded to the left with a zero if necessary. 1. Let _day_ be _monthDay_.[[ISODay]] formatted as a two-digit decimal number, padded to the left with a zero if necessary. 1. Let _result_ be the string-concatenation of _month_, the code unit 0x002D (HYPHEN-MINUS), and _day_. - 1. If _calendar_ is not the empty String, then + 1. Let _calendar_ be _monthDay_.[[Calendar]]. + 1. Let _calendarString_ be ? FormatCalendarAnnotation(_calendar_, _showCalendar_). + 1. If _calendarString_ is not the empty String, or _calendar_ does not have an [[InitializedTemporalCalendar]] internal slot, or _calendar_.[[Identifier]] is not *"iso8601"*, then 1. Let _year_ be ! PadYear(_monthDay_.[[ISOYear]]). - 1. Set _result_ to the string-concatenation of _year_, the code unit 0x002D (HYPHEN-MINUS), _result_, and _calendar_. + 1. Set _result_ to the string-concatenation of _year_, the code unit 0x002D (HYPHEN-MINUS), _result_, and _calendarString_. 1. Return _result_.
diff --git a/spec/yearmonth.html b/spec/yearmonth.html index eadd2045af..bd92ebf00e 100644 --- a/spec/yearmonth.html +++ b/spec/yearmonth.html @@ -356,14 +356,17 @@

Temporal.YearMonth.prototype.equals ( _other_ )

-

Temporal.YearMonth.prototype.toString ( )

+

Temporal.YearMonth.prototype.toString ( [ _options_ ] )

+ The `toString` method takes one argument _options_. The following steps are taken:

1. Let _yearMonth_ be the *this* value. 1. Perform ? RequireInternalSlot(_yearMonth_, [[InitializedTemporalYearMonth]]). - 1. Return ! TemporalYearMonthToString(_yearMonth_). + 1. Set _options_ to ? NormalizeOptionsObject(_options_). + 1. Let _showCalendar_ be ? ToShowCalendarOption(_options_). + 1. Return ! TemporalYearMonthToString(_yearMonth_, _showCalendar_).
@@ -377,7 +380,7 @@

Temporal.YearMonth.prototype.toLocaleString ( [ _locales_ [ , _options_ ] ] 1. Let _yearMonth_ be the *this* value. 1. Perform ? RequireInternalSlot(_yearMonth_, [[InitializedTemporalYearMonth]]). 1. If the implementation does not include the ECMA-402 Internationalization API, then - 1. Return ! TemporalYearMonthToString(_yearMonth_). + 1. Return ! TemporalYearMonthToString(_yearMonth_, *"auto"*). 1. Let _dateFormat_ be ? Construct(%DateTimeFormat%, « _locales_, _options_ »). 1. Return ? FormatDateTime(_dateFormat_, _yearMonth_). @@ -391,7 +394,7 @@

Temporal.YearMonth.prototype.toJSON ( )

1. Let _yearMonth_ be the *this* value. 1. Perform ? RequireInternalSlot(_yearMonth_, [[InitializedTemporalYearMonth]]). - 1. Return ! TemporalYearMonthToString(_yearMonth_). + 1. Return ! TemporalYearMonthToString(_yearMonth_, *"auto"*). @@ -700,17 +703,18 @@

ToTemporalYearMonthFields ( _temporalYearMonthLike_, _fieldNames_ )

-

TemporalYearMonthToString ( _yearMonth_ )

+

TemporalYearMonthToString ( _yearMonth_, _showCalendar_ )

1. Assert: Type(_yearMonth_) is Object. 1. Assert: _yearMonth_ has an [[InitializedTemporalYearMonth]] internal slot. 1. Let _year_ be ! PadYear(_yearMonth_.[[ISOYear]]). 1. Let _month_ be _yearMonth_.[[ISOMonth]] formatted as a two-digit decimal number, padded to the left with a zero if necessary. - 1. Let _calendar_ be ? FormatCalendarAnnotation(_yearMonth_.[[Calendar]]). + 1. Let _calendar_ be _yearMonth_.[[Calendar]]. + 1. Let _calendarString_ be ? FormatCalendarAnnotation(_calendar_, _showCalendar_). 1. Let _result_ be the string-concatenation of _year_, the code unit 0x002D (HYPHEN-MINUS), and _month_. - 1. If _calendar_ is not the empty String, then + 1. If _calendarString_ is not the empty String, or _calendar_ does not have an [[InitializedTemporalCalendar]] internal slot, or _calendar_.[[Identifier]] is not *"iso8601"*, then 1. Let _day_ be _yearMonth_.[[ISODay]] formatted as a two-digit decimal number, padded to the left with a zero if necessary. - 1. Set _result_ to the string-concatenation of _result_, the code unit 0x002D (HYPHEN-MINUS), _day_, and _calendar_. + 1. Set _result_ to the string-concatenation of _result_, the code unit 0x002D (HYPHEN-MINUS), _day_, and _calendarString_. 1. Return _result_.
diff --git a/spec/zoneddatetime.html b/spec/zoneddatetime.html index 6658b8d868..ec30a7cce1 100644 --- a/spec/zoneddatetime.html +++ b/spec/zoneddatetime.html @@ -725,7 +725,8 @@

Temporal.ZonedDateTime.prototype.toString ( [ _options_ ] )

1. Set _options_ to ? NormalizeOptionsObject(_options_). 1. Let _precision_ be ? ToSecondsStringPrecision(_options_). 1. Let _roundingMode_ be ? ToTemporalRoundingMode(_options_, *"trunc"*). - 1. Return ? TemporalZonedDateTimeToString(_zonedDateTime_, _precision_.[[Precision]], _precision_.[[Increment]], _precision_.[[Unit]], _roundingMode_). + 1. Let _showCalendar_ be ? ToShowCalendarOption(_options_). + 1. Return ? TemporalZonedDateTimeToString(_zonedDateTime_, _precision_.[[Precision]], _showCalendar_, _precision_.[[Increment]], _precision_.[[Unit]], _roundingMode_). @@ -739,7 +740,7 @@

Temporal.ZonedDateTime.prototype.toLocaleString ( [ _locales_ [ , _options_ 1. Let _zonedDateTime_ be the *this* value. 1. Perform ? RequireInternalSlot(_zonedDateTime_, [[InitializedTemporalZonedDateTime]]). 1. If the implementation does not include the ECMA-402 Internationalization API, then - 1. Return ? TemporalZonedDateTimeToString(_zonedDateTime_, *"auto"*). + 1. Return ? TemporalZonedDateTimeToString(_zonedDateTime_, *"auto"*, *"auto"*). 1. Let _dateFormat_ be ? Construct(%DateTimeFormat%, « _locales_, _options_ »). 1. Return ? FormatDateTime(_dateFormat_, _zonedDateTime_). @@ -753,7 +754,7 @@

Temporal.ZonedDateTime.prototype.toJSON ( )

1. Let _zonedDateTime_ be the *this* value. 1. Perform ? RequireInternalSlot(_zonedDateTime_, [[InitializedTemporalZonedDateTime]]). - 1. Return ? TemporalZonedDateTimeToString(_zonedDateTime_, *"auto"*). + 1. Return ? TemporalZonedDateTimeToString(_zonedDateTime_, *"auto"*, *"auto"*). @@ -1044,7 +1045,7 @@

CreateTemporalZonedDateTimeFromStatic ( _constructor_, _epochNanoseconds_, _ -

TemporalZonedDateTimeToString ( _zonedDateTime_, _precision_ [ , _increment_, _unit_, _roundingMode_ ] )

+

TemporalZonedDateTimeToString ( _zonedDateTime_, _precision_, _showCalendar_ [ , _increment_, _unit_, _roundingMode_ ] )

The abstract operation TemporalZonedDateTimeToString returns an ISO 8601 string representation of its argument, including a time zone name annotation and calendar annotation, which are extensions to the ISO 8601 format.

@@ -1059,10 +1060,10 @@

TemporalZonedDateTimeToString ( _zonedDateTime_, _precision_ [ , _increment_ 1. Let _result_ be ? RoundDateTime(_dateTime_.[[ISOYear]], _dateTime_.[[ISOMonth]], _dateTime_.[[ISODay]], _dateTime_.[[Hour]], _dateTime_.[[Minute]], _dateTime_.[[Second]], _dateTime_.[[Millisecond]], _dateTime_.[[Microsecond]], _dateTime_.[[Nanosecond]], _increment_, _unit_, _roundingMode_). 1. TODO: Do something if _result_ is a nonexistent wall-clock time. 1. Let _isoCalendar_ be ? GetISO8601Calendar(). - 1. Let _dateTimeString_ be ? TemporalDateTimeToString(_result_.[[Year]], _result_.[[Month]], _result_.[[Day]], _result_.[[Hour]], _result_.[[Minute]], _result_.[[Second]], _result_.[[Millisecond]], _result_.[[Microsecond]], _result_.[[Nanosecond]], _isoCalendar_, _precision_). + 1. Let _dateTimeString_ be ? TemporalDateTimeToString(_result_.[[Year]], _result_.[[Month]], _result_.[[Day]], _result_.[[Hour]], _result_.[[Minute]], _result_.[[Second]], _result_.[[Millisecond]], _result_.[[Microsecond]], _result_.[[Nanosecond]], _isoCalendar_, _precision_, *"never"*). 1. Let _offsetString_ be ? GetOffsetStringFor(_timeZone_, _instant_). 1. Let _timeZoneString_ be ? TimeZoneToString(_timeZone_). - 1. Let _calendarString_ be ? FormatCalendarAnnotation(_zonedDateTime_.[[Calendar]]). + 1. Let _calendarString_ be ? FormatCalendarAnnotation(_zonedDateTime_.[[Calendar]], _showCalendar_). 1. Return the string-concatenation of _dateTimeString_, _offsetString_, the code unit 0x005B (LEFT SQUARE BRACKET), _timeZoneString_, the code unit 0x005D (RIGHT SQUARE BRACKET), and _calendarString_.