diff --git a/docs/calendar.md b/docs/calendar.md index 72853cc97e..269769f2ac 100644 --- a/docs/calendar.md +++ b/docs/calendar.md @@ -179,44 +179,8 @@ date.daysInYear; // => 355 date.calendar.daysInYear(date); // same result, but calling the method directly ``` -### calendar.**hour**(_time_: Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime | object | string) : number - -### calendar.**minute**(_time_: Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime | object | string) : number - -### calendar.**second**(_time_: Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime | object | string) : number - -### calendar.**millisecond**(_time_: Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime | object | string) : number - -### calendar.**microsecond**(_time_: Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime | object | string) : number - -### calendar.**nanosecond**(_time_: Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime | object | string) : number - -The above methods are all similar. -They provide a way to query properties of a particular time in the calendar's time reckoning. - -**Parameters:** - -- `time` (`Temporal.PlainTime`, or value convertible to one): A time. - -**Returns:** some piece of data (hour, minute, second, etc., depending on the method) associated with `time`, in `calendar`'s calendar system. - -If `time` is not one of the appropriate Temporal objects, then it will be converted to a `Temporal.PlainTime` as if it were passed to `Temporal.PlainTime.from()`. - -None of the above methods need to be called directly except in specialized code. -They are called indirectly when reading the various properties of `Temporal.ZonedDateTime`, `Temporal.PlainDateTime`, `Temporal.PlainTime`. - -For example: - -```javascript -const time = Temporal.PlainTime.from('03:20:00').withCalendar('ethiopic'); -time.hour; // => 9 -time.calendar.hour(time); // same result, but calling the method directly -``` - ### calendar.**dateFromFields**(_fields_: object, _options_: object, _constructor_: function) : Temporal.PlainDate -### calendar.**timeFromFields**(_fields_: object, _options_: object, _constructor_: function) : Temporal.PlainTime - ### calendar.**yearMonthFromFields**(_fields_: object, _options_: object, _constructor_: function) : Temporal.PlainYearMonth ### calendar.**monthDayFromFields**(_fields_: object, _options_: object, _constructor_: function) : Temporal.PlainMonthDay @@ -226,7 +190,7 @@ They provide a way to construct other Temporal objects from values in the calend **Parameters:** -- `fields` (object): An object with properties similar to what is passed to `Temporal.PlainDate.from()`, `Temporal.PlainTime.from()`, `Temporal.PlainYearMonth.from()`, or `Temporal.PlainMonthDay.from()`, respectively. +- `fields` (object): An object with properties similar to what is passed to `Temporal.PlainDate.from()`, `Temporal.PlainYearMonth.from()`, or `Temporal.PlainMonthDay.from()`, respectively. - `options`: (object): An object with properties representing options for constructing the Temporal object. The following options are recognized: - `overflow` (string): How to deal with out-of-range values in `fields`. @@ -238,7 +202,7 @@ They provide a way to construct other Temporal objects from values in the calend **Returns:** a new object of the type of `constructor`. None of the above methods need to be called directly except in specialized code. -They are called indirectly when using `Temporal.PlainDate.from()`, `Temporal.PlainTime.from()`, `Temporal.PlainDateTime.from()`, `Temporal.PlainYearMonth.from()`, and `Temporal.PlainMonthDay.from()`. +They are called indirectly when using `Temporal.PlainDate.from()`, `Temporal.PlainDateTime.from()`, `Temporal.PlainYearMonth.from()`, and `Temporal.PlainMonthDay.from()`. For example: @@ -309,54 +273,6 @@ date.day; // => 7 date.toString(); // => 2020-06-28[c=islamic] ``` -### calendar.**timeAdd**(_time_: Temporal.PlainTime | object | string, _duration_: Temporal.Duration | object | string, _options_: object, _constructor_: function) : Temporal.PlainDate - -This method provides a way to do time arithmetic in the calendar's time reckoning. - -**Parameters:** - -- `time` (`Temporal.PlainTime`, or value convertible to one): A time. -- `duration` (`Temporal.Duration`, or value convertible to one): A duration to add to `time`. - For subtraction, add a negative duration. -- `options` (object): An object with properties representing options for performing the addition or subtraction. - The following options are recognized: - - `overflow` (string): How to deal with out-of-range values in the result of the addition or subtraction. - Allowed values are `constrain` and `reject`. - The default is `constrain`. -- `constructor` (function): The constructor function of the Temporal type to construct. - This is used when subclassing Temporal objects. - -**Returns:** a new object of the type of `constructor`. - -If `time` is not a `Temporal.PlainTime` object, or `duration` not a `Temporal.Duration` object, then they will be converted to one as if they were passed to `Temporal.PlainTime.from()` or `Temporal.Duration.from()`, respectively. - -This method does not need to be called directly except in specialized code. -It is called indirectly when using `add()` and `subtract()` of `Temporal.PlainDateTime`, and `Temporal.PlainTime`. - -For example: - -```javascript -time = Temporal.PlainTime.from('03:20:00') - .withCalendar('ethiopic') - .add(Temporal.Duration.from({ minutes: 1 }), { overflow: 'reject' }); -time.hour; // => 9 -time.minute; // => 21 -time.second; // => 0 -time.toString(); // => 03:21:00[c=ethiopic] - -// same result, but calling the method directly: -time = Temporal.Calendar.from('ethiopic').timeAdd( - Temporal.PlainTime.from('03:20:00'), - Temporal.Duration.from({ minutes: 1 }), - { overflow: 'reject' }, - Temporal.PlainTime -); -time.hour; // => 9 -time.minute; // => 21 -time.second; // => 0 -time.toString(); // => 03:20:00[c=ethiopic] -``` - ### calendar.**dateUntil**(_one_: Temporal.PlainDate | object | string, _two_: Temporal.PlainDate | object | string, _options_: object) : Temporal.Duration **Parameters:** @@ -395,42 +311,6 @@ Temporal.Calendar.from('chinese').dateUntil( ); // => P1M2D ``` -### calendar.**timeUntil**(_one_: Temporal.PlainTime | object | string, _two_: Temporal.PlainTime | object | string, _options_: object) : Temporal.Duration - -**Parameters:** - -- `one` (`Temporal.PlainTime`, or value convertible to one): A time. -- `two` (`Temporal.PlainTime`, or value convertible to one): Another time. -- `options` (object): An object with properties representing options for the operation. - The following options are recognized: - - `largestUnit` (optional string): The largest unit of time to allow in the resulting `Temporal.Duration` object. - Valid values are `'auto'`, `'hours'`, `'minutes'`, `'seconds'`, `'milliseconds'`, `microseconds'` and `'nanoseconds'`. - The default is `'auto'`. - -**Returns:** a `Temporal.Duration` representing the time elapsed after `one` and until `two`. - -If either of `one` or `two` are not `Temporal.PlainTime` objects, then they will be converted to one as if they were passed to `Temporal.PlainTime.from()`. - -This method does not need to be called directly except in specialized code. -It is called indirectly when using the `until()` and `since()` methods of `Temporal.PlainDateTime`, and `Temporal.PlainTime`. - -If `one` is later than `two`, then the resulting duration should be negative. - -The default `largestUnit` value of `'auto'` is the same as `'hours'`. - -For example: - -```javascript -t1 = Temporal.PlainTime.from('03:10:00').withCalendar('ethiopic'); -t2 = Temporal.PlainTime.from('03:30:00').withCalendar('ethiopic'); -t1.until(t2, { largestUnit: 'minutes' }); // => PT20M - -// same result, but calling the method directly: -Temporal.Calendar.from('ethiopic').timeUntil(Temporal.PlainTime.from('03:10:00'), Temporal.PlainTime.from('03:30:00'), { - largestUnit: 'minutes' -}); // => PT20M -``` - ### calendar.**fields**(fields: array) : array **Parameters:** @@ -440,9 +320,9 @@ Temporal.Calendar.from('ethiopic').timeUntil(Temporal.PlainTime.from('03:10:00') **Returns:** a new list of field names. This method does not need to be called directly except in specialized code. -It is called indirectly when using the `from()` static methods and `with()` methods of `Temporal.PlainDateTime`, `Temporal.PlainDate`, `Temporal.PlainTime`, and `Temporal.PlainYearMonth`. +It is called indirectly when using the `from()` static methods and `with()` methods of `Temporal.PlainDateTime`, `Temporal.PlainDate`, and `Temporal.PlainYearMonth`. -Custom calendars should override this method if they require more fields with which to denote the date than the standard `year`, `month`, `day`, `hour`, `minute`, `second`, `millisecond`, `microsecond`, and `nanosecond` (for example, `era`). +Custom calendars should override this method if they require more fields with which to denote the date than the standard `year`, `month`, and `day` (for example, `era`). The input array contains the field names that are necessary for a particular operation (for example, `'month'` and `'day'` for `Temporal.PlainMonthDay.prototype.with()`), and the method should make a copy of the array and add whichever extra fields are necessary. When subclassing `Temporal.Calendar`, this method doesn't need to be overridden, unless your calendar requires extra fields, because the default implementation returns a copy of `fields`. diff --git a/docs/plaintime.md b/docs/plaintime.md index 3280477c83..58ee882ebc 100644 --- a/docs/plaintime.md +++ b/docs/plaintime.md @@ -15,7 +15,7 @@ It can also be combined with a `Temporal.PlainDate` to yield a "zoneless" `Tempo ## Constructor -### **new Temporal.PlainTime**(_isoHour_: number = 0, _isoMinute_: number = 0, _isoSecond_: number = 0, _isoMillisecond_: number = 0, _isoMicrosecond_: number = 0, _isoNanosecond_: number = 0, _calendar_?: object) : Temporal.PlainTime +### **new Temporal.PlainTime**(_isoHour_: number = 0, _isoMinute_: number = 0, _isoSecond_: number = 0, _isoMillisecond_: number = 0, _isoMicrosecond_: number = 0, _isoNanosecond_: number = 0) : Temporal.PlainTime **Parameters:** @@ -25,15 +25,13 @@ It can also be combined with a `Temporal.PlainDate` to yield a "zoneless" `Tempo - `isoMillisecond` (optional number): A number of milliseconds, ranging between 0 and 999 inclusive. - `isoMicrosecond` (optional number): A number of microseconds, ranging between 0 and 999 inclusive. - `isoNanosecond` (optional number): A number of nanoseconds, ranging between 0 and 999 inclusive. -- `calendar` (optional `Temporal.Calendar` or plain object): A calendar to project the time into. **Returns:** a new `Temporal.PlainTime` object. Use this constructor if you have the correct parameters for the time already as individual number values in the ISO 8601 calendar. -Otherwise, `Temporal.PlainTime.from()`, which accepts more kinds of input, allows inputting times in different calendar reckonings, and allows controlling the overflow behaviour, is probably more convenient. +Otherwise, `Temporal.PlainTime.from()`, which accepts more kinds of input and allows controlling the overflow behaviour, is probably more convenient. All values are given as reckoned in the [ISO 8601 calendar](https://en.wikipedia.org/wiki/ISO_8601#Dates). -Together, `isoHour`, `isoMinute`, `isoSecond`, `isoMillisecond`, `isoMicrosecond`, and `isoNanosecond` must represent a valid date in that calendar, even if you are passing a different calendar as the `calendar` parameter. Usage examples: @@ -59,10 +57,10 @@ time = new Temporal.PlainTime(13, 37); // => 13:37 This static method creates a new `Temporal.PlainTime` object from another value. If the value is another `Temporal.PlainTime` object, a new object representing the same time is returned. -If the value is any other object, a `Temporal.PlainTime` will be constructed from the values of any `hour`, `minute`, `second`, `millisecond`, `microsecond`, `nanosecond`, and `calendar` properties that are present. -Any missing ones except `calendar` will be assumed to be 0. +If the value is any other object, a `Temporal.PlainTime` will be constructed from the values of any `hour`, `minute`, `second`, `millisecond`, `microsecond`, and `nanosecond` properties that are present. +Any missing ones will be assumed to be 0. -If the `calendar` property is not present, it will be assumed to be `Temporal.Calendar.from('iso8601')`, the [ISO 8601 calendar](https://en.wikipedia.org/wiki/ISO_8601#Dates). +If the `calendar` property is present, it must be the string `'iso8601'` or the [ISO 8601 calendar](https://en.wikipedia.org/wiki/ISO_8601#Dates), for future compatibility. Any non-object value will be converted to a string, which is expected to be in ISO 8601 format. If the string designates a date or a time zone, they will be ignored. @@ -171,9 +169,9 @@ time.nanosecond; // => 205 ``` -### time.**calendar**: object +### time.**calendar**: Temporal.Calendar -The `calendar` read-only property gives the calendar that the `hour`, `minute`, `second`, `millisecond`, `microsecond`, and `nanosecond` properties are interpreted in. +The value of the `calendar` read-only property is always the ISO 8601 calendar, for future compatibility. ## Methods @@ -195,7 +193,7 @@ This method creates a new `Temporal.PlainTime` which is a copy of `time`, but an Since `Temporal.PlainTime` objects are immutable, use this method instead of modifying one. > **NOTE**: `calendar` and `timeZone` properties are not allowed on `timeLike`. -> See the `withCalendar` and `toZonedDateTime` methods instead. +> See the `toPlainDateTime` and `toZonedDateTime` methods instead. Usage example: @@ -211,21 +209,6 @@ time.add({ hours: 1 }).with({ }); // => 20:00 ``` -### time.**withCalendar**(_calendar_: object | string) : Temporal.PlainTime - -**Parameters:** - -- `calendar` (`Temporal.Calendar` or plain object or string): The calendar into which to project `time`. - -**Returns:** a new `Temporal.PlainTime` object which is the time indicated by `time`, projected into `calendar`. - -Usage example: - -```javascript -time = Temporal.PlainTime.from('03:20:00[c=ethiopic]'); -time.withCalendar('iso8601'); // => 03:20:00 -``` - ### time.**add**(_duration_: Temporal.Duration | object | string, _options_?: object) : Temporal.PlainTime **Parameters:** @@ -464,9 +447,6 @@ time.equals(time); // => true - `options` (optional object): An object with properties representing options for the operation. The following options are recognized: - - `calendarName` (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'`. @@ -488,10 +468,6 @@ 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.PlainDateTime.round()`. Note that rounding may change the value of other units as well. -Normally, a calendar annotation is shown when `time`'s calendar is not the ISO 8601 calendar. -By setting the `calendarName` 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: @@ -639,14 +615,14 @@ date = Temporal.PlainDate.from('2006-08-24'); time.toPlainDateTime(date); // => 2006-08-24T15:23:30.003 ``` -### time.**getFields**() : { hour: number, minute: number, second: number, millisecond: number, microsecond: number, nanosecond: number } +### time.**getFields**() : { hour: number, minute: number, second: number, millisecond: number, microsecond: number, nanosecond: number, calendar: Temporal.Calendar } **Returns:** a plain object with properties equal to the fields of `time`. This method can be used to convert a `Temporal.PlainTime` into a record-like data structure. It returns a new plain JavaScript object, with all the fields as enumerable, writable, own data properties. -Note that if using a different calendar from ISO 8601, these will be the calendar-specific values and may include extra properties. +A `calendar` property is included and is always set to the ISO 8601 calendar. Usage example: @@ -656,13 +632,12 @@ Object.assign({}, time).minute; // => undefined Object.assign({}, time.getFields()).minute; // => 23 ``` -### time.**getISOFields**(): { isoHour: number, isoMinute: number, isoSecond: number, isoMillisecond: number, isoMicrosecond: number, isoNanosecond: number, calendar: object } +### time.**getISOFields**(): { isoHour: number, isoMinute: number, isoSecond: number, isoMillisecond: number, isoMicrosecond: number, isoNanosecond: number, calendar: Temporal.Calendar } -**Returns:** a plain object with properties expressing `time` in the ISO 8601 calendar, as well as the value of `time.calendar`. +**Returns:** a plain object with properties expressing `time` in the ISO 8601 calendar. -This method is mainly useful if you are implementing a custom calendar. -Most code will not need to use it. -Use `time.getFields()` instead, or `time.withCalendar('iso8601').getFields()`. +This method is present for forward compatibility with custom calendars. +Use `time.getFields()` instead. Usage example: @@ -670,23 +645,4 @@ Usage example: time = Temporal.PlainTime.from('03:20:00'); f = time.getISOFields(); f.isoHour; // => 3 -// Fields correspond exactly to constructor arguments: -time2 = new Temporal.PlainTime( - f.isoHour, - f.isoMinute, - f.isoSecond, - f.isoMillisecond, - f.isoMicrosecond, - f.isoNanosecond, - f.calendar -); -time.equals(time2); // => true - -// Time in other calendar -time = time.withCalendar('ethiopic'); -time.getFields().hour; // => 9 -time.getISOFields().isoHour; // => 3 - -// Most likely what you need is this: -time.withCalendar('iso8601').hour; // => 3 ``` diff --git a/polyfill/index.d.ts b/polyfill/index.d.ts index a7e1c23e20..01cb51d928 100644 --- a/polyfill/index.d.ts +++ b/polyfill/index.d.ts @@ -1076,6 +1076,7 @@ export namespace Temporal { millisecond?: number; microsecond?: number; nanosecond?: number; + calendar?: Temporal.Calendar | 'iso8601'; }; type TimeFields = { @@ -1085,6 +1086,7 @@ export namespace Temporal { millisecond: number; microsecond: number; nanosecond: number; + calendar: Temporal.Calendar; }; /** @@ -1122,6 +1124,7 @@ export namespace Temporal { readonly millisecond: number; readonly microsecond: number; readonly nanosecond: number; + readonly calendar: Temporal.Calendar; equals(other: Temporal.PlainTime | TimeLike | string): boolean; with(timeLike: Temporal.PlainTime | TimeLike, options?: AssignmentOptions): Temporal.PlainTime; add( @@ -1188,9 +1191,10 @@ export namespace Temporal { plainDate: Temporal.PlainDate | DateLike | string; }): Temporal.ZonedDateTime; getFields(): TimeFields; + getISOFields(): TimeFields; toLocaleString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string; toJSON(): string; - toString(options?: CalendarTypeToStringOptions): string; + toString(options?: ToStringPrecisionOptions): string; valueOf(): never; } @@ -1625,23 +1629,6 @@ export namespace Temporal { */ export function dateISO(tzLike?: TimeZoneProtocol | string): Temporal.PlainDate; - /** - * Get the current clock time in a specific time zone. - * - * @param {Temporal.Calendar | string} [calendar] - calendar identifier, or - * a `Temporal.Calendar` instance, or an object implementing the calendar - * protocol. - * @param {TimeZoneProtocol | string} [tzLike] - - * {@link https://en.wikipedia.org/wiki/List_of_tz_database_time_zones|IANA time zone identifier} - * string (e.g. `'Europe/London'`), `Temporal.TimeZone` instance, or an - * object implementing the time zone protocol. If omitted, - * the environment's current time zone will be used. - */ - export function plainTime( - calendar: CalendarProtocol | string, - tzLike?: TimeZoneProtocol | string - ): Temporal.PlainDate; - /** * Get the current clock time in a specific time zone, using the ISO 8601 calendar. * diff --git a/polyfill/lib/calendar.mjs b/polyfill/lib/calendar.mjs index 1893753b04..8a3d2b0d44 100644 --- a/polyfill/lib/calendar.mjs +++ b/polyfill/lib/calendar.mjs @@ -10,12 +10,6 @@ import { ISO_YEAR, ISO_MONTH, ISO_DAY, - ISO_HOUR, - ISO_MINUTE, - ISO_SECOND, - ISO_MILLISECOND, - ISO_MICROSECOND, - ISO_NANOSECOND, TIME_ZONE, CreateSlots, GetSlot, @@ -50,12 +44,6 @@ export class Calendar { void constructor; throw new Error('not implemented'); } - timeFromFields(fields, options, constructor) { - void fields; - void options; - void constructor; - throw new Error('not implemented'); - } yearMonthFromFields(fields, options, constructor) { void fields; void options; @@ -85,19 +73,6 @@ export class Calendar { void options; throw new Error('not implemented'); } - timeAdd(time, duration, options, constructor) { - void time; - void duration; - void options; - void constructor; - throw new Error('not implemented'); - } - timeUntil(one, two, options) { - void one; - void two; - void options; - throw new Error('not implemented'); - } year(date) { void date; throw new Error('not implemented'); @@ -142,30 +117,6 @@ export class Calendar { void date; throw new Error('not implemented'); } - hour(time) { - void time; - throw new Error('not implemented'); - } - minute(time) { - void time; - throw new Error('not implemented'); - } - second(time) { - void time; - throw new Error('not implemented'); - } - millisecond(time) { - void time; - throw new Error('not implemented'); - } - microsecond(time) { - void time; - throw new Error('not implemented'); - } - nanosecond(time) { - void time; - throw new Error('not implemented'); - } toString() { if (!ES.IsTemporalCalendar(this)) throw new TypeError('invalid receiver'); return GetSlot(this, CALENDAR_ID); @@ -208,29 +159,6 @@ class ISO8601Calendar extends Calendar { ({ year, month, day } = ES.RegulateDate(year, month, day, overflow)); return new constructor(year, month, day, this); } - timeFromFields(fields, options, constructor) { - if (!ES.IsTemporalCalendar(this)) throw new TypeError('invalid receiver'); - options = ES.NormalizeOptionsObject(options); - const overflow = ES.ToTemporalOverflow(options); - let { hour, minute, second, millisecond, microsecond, nanosecond } = ES.ToRecord(fields, [ - ['hour', 0], - ['microsecond', 0], - ['millisecond', 0], - ['minute', 0], - ['nanosecond', 0], - ['second', 0] - ]); - ({ hour, minute, second, millisecond, microsecond, nanosecond } = ES.RegulateTime( - hour, - minute, - second, - millisecond, - microsecond, - nanosecond, - overflow - )); - return new constructor(hour, minute, second, millisecond, microsecond, nanosecond, this); - } yearMonthFromFields(fields, options, constructor) { if (!ES.IsTemporalCalendar(this)) throw new TypeError('invalid receiver'); options = ES.NormalizeOptionsObject(options); @@ -286,66 +214,6 @@ class ISO8601Calendar extends Calendar { const Duration = GetIntrinsic('%Temporal.Duration%'); return new Duration(years, months, weeks, days, 0, 0, 0, 0, 0, 0); } - timeAdd(time, duration, options, constructor) { - if (!ES.IsTemporalCalendar(this)) throw new TypeError('invalid receiver'); - time = ES.ToTemporalTime(time, GetIntrinsic('%Temporal.PlainTime%')); - duration = ES.ToTemporalDuration(duration, GetIntrinsic('%Temporal.Duration%')); - options = ES.NormalizeOptionsObject(options); - const overflow = ES.ToTemporalOverflow(options); - const { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = duration; - ES.RejectDurationSign(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds); - let hour = GetSlot(time, ISO_HOUR); - let minute = GetSlot(time, ISO_MINUTE); - let second = GetSlot(time, ISO_SECOND); - let millisecond = GetSlot(time, ISO_MILLISECOND); - let microsecond = GetSlot(time, ISO_MICROSECOND); - let nanosecond = GetSlot(time, ISO_NANOSECOND); - ({ hour, minute, second, millisecond, microsecond, nanosecond } = ES.AddTime( - hour, - minute, - second, - millisecond, - microsecond, - nanosecond, - hours, - minutes, - seconds, - milliseconds, - microseconds, - nanoseconds - )); - ({ hour, minute, second, millisecond, microsecond, nanosecond } = ES.RegulateTime( - hour, - minute, - second, - millisecond, - microsecond, - nanosecond, - overflow - )); - return new constructor(hour, minute, second, millisecond, microsecond, nanosecond, this); - } - timeUntil(one, two) { - if (!ES.IsTemporalCalendar(this)) throw new TypeError('invalid receiver'); - one = ES.ToTemporalTime(one, GetIntrinsic('%Temporal.PlainTime%')); - two = ES.ToTemporalTime(two, GetIntrinsic('%Temporal.PlainTime%')); - let { deltaDays, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = ES.DifferenceTime( - GetSlot(one, ISO_HOUR), - GetSlot(one, ISO_MINUTE), - GetSlot(one, ISO_SECOND), - GetSlot(one, ISO_MILLISECOND), - GetSlot(one, ISO_MICROSECOND), - GetSlot(one, ISO_NANOSECOND), - GetSlot(two, ISO_HOUR), - GetSlot(two, ISO_MINUTE), - GetSlot(two, ISO_SECOND), - GetSlot(two, ISO_MILLISECOND), - GetSlot(two, ISO_MICROSECOND), - GetSlot(two, ISO_NANOSECOND) - ); - const Duration = GetIntrinsic('%Temporal.Duration%'); - return new Duration(0, 0, 0, deltaDays, hours, minutes, seconds, milliseconds, microseconds, nanoseconds); - } year(date) { if (!ES.IsTemporalCalendar(this)) throw new TypeError('invalid receiver'); if (!HasSlot(date, ISO_YEAR)) date = ES.ToTemporalDate(date, GetIntrinsic('%Temporal.PlainDate%')); @@ -361,30 +229,6 @@ class ISO8601Calendar extends Calendar { if (!HasSlot(date, ISO_DAY)) date = ES.ToTemporalDate(date, GetIntrinsic('%Temporal.PlainDate%')); return GetSlot(date, ISO_DAY); } - hour(time) { - if (!ES.IsTemporalCalendar(this)) throw new TypeError('invalid receiver'); - return GetSlot(time, ISO_HOUR); - } - minute(time) { - if (!ES.IsTemporalCalendar(this)) throw new TypeError('invalid receiver'); - return GetSlot(time, ISO_MINUTE); - } - second(time) { - if (!ES.IsTemporalCalendar(this)) throw new TypeError('invalid receiver'); - return GetSlot(time, ISO_SECOND); - } - millisecond(time) { - if (!ES.IsTemporalCalendar(this)) throw new TypeError('invalid receiver'); - return GetSlot(time, ISO_MILLISECOND); - } - microsecond(time) { - if (!ES.IsTemporalCalendar(this)) throw new TypeError('invalid receiver'); - return GetSlot(time, ISO_MICROSECOND); - } - nanosecond(time) { - if (!ES.IsTemporalCalendar(this)) throw new TypeError('invalid receiver'); - return GetSlot(time, ISO_NANOSECOND); - } dayOfWeek(date) { if (!ES.IsTemporalCalendar(this)) throw new TypeError('invalid receiver'); date = ES.ToTemporalDate(date, GetIntrinsic('%Temporal.PlainDate%')); diff --git a/polyfill/lib/ecmascript.mjs b/polyfill/lib/ecmascript.mjs index abb6a09f29..4b13c8d850 100644 --- a/polyfill/lib/ecmascript.mjs +++ b/polyfill/lib/ecmascript.mjs @@ -680,17 +680,7 @@ export const ES = ObjectAssign({}, ES2020, { calendar = relativeTo.calendar; if (calendar === undefined) calendar = GetISO8601Calendar(); calendar = ES.ToTemporalCalendar(calendar); - const fieldNames = ES.CalendarFields(calendar, [ - 'day', - 'hour', - 'microsecond', - 'millisecond', - 'minute', - 'month', - 'nanosecond', - 'second', - 'year' - ]); + const fieldNames = ES.CalendarFields(calendar, ['day', 'month', 'year']); const fields = ES.ToTemporalDateTimeFields(relativeTo, fieldNames); ({ year, @@ -919,22 +909,15 @@ export const ES = ObjectAssign({}, ES2020, { }); return ES.ToRecord(bag, entries); }, - ToTemporalTimeFields: (bag, fieldNames) => { - const entries = [ + ToTemporalTimeRecord: (bag) => { + return ES.ToRecord(bag, [ ['hour', 0], ['microsecond', 0], ['millisecond', 0], ['minute', 0], ['nanosecond', 0], ['second', 0] - ]; - // Add extra fields from the calendar at the end - fieldNames.forEach((fieldName) => { - if (!entries.some(([name]) => name === fieldName)) { - entries.push([fieldName, undefined]); - } - }); - return ES.ToRecord(bag, entries); + ]); }, ToTemporalYearMonthFields: (bag, fieldNames) => { const entries = [['month'], ['year']]; @@ -993,16 +976,16 @@ export const ES = ObjectAssign({}, ES2020, { const year = GetSlot(date, ISO_YEAR); const month = GetSlot(date, ISO_MONTH); const day = GetSlot(date, ISO_DAY); - - const TemporalTime = GetIntrinsic('%Temporal.PlainTime%'); - const time = ES.TimeFromFields(calendar, fields, TemporalTime, overflow); - const hour = GetSlot(time, ISO_HOUR); - const minute = GetSlot(time, ISO_MINUTE); - const second = GetSlot(time, ISO_SECOND); - const millisecond = GetSlot(time, ISO_MILLISECOND); - const microsecond = GetSlot(time, ISO_MICROSECOND); - const nanosecond = GetSlot(time, ISO_NANOSECOND); - + let { hour, minute, second, millisecond, microsecond, nanosecond } = ES.ToTemporalTimeRecord(fields); + ({ hour, minute, second, millisecond, microsecond, nanosecond } = ES.RegulateTime( + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + overflow + )); return { year, month, day, hour, minute, second, millisecond, microsecond, nanosecond }; }, ToTemporalDateTime: (item, constructor, overflow = 'constrain') => { @@ -1131,26 +1114,25 @@ export const ES = ObjectAssign({}, ES2020, { return result; }, ToTemporalTime: (item, constructor, overflow = 'constrain') => { + let hour, minute, second, millisecond, microsecond, nanosecond, calendar; if (ES.Type(item) === 'Object') { if (ES.IsTemporalTime(item)) return item; - let calendar = item.calendar; - if (calendar === undefined) calendar = new (GetIntrinsic('%Temporal.ISO8601Calendar%'))(); - calendar = ES.ToTemporalCalendar(calendar); - const fieldNames = ES.CalendarFields(calendar, [ - 'hour', - 'microsecond', - 'millisecond', - 'minute', - 'nanosecond', - 'second' - ]); - const fields = ES.ToTemporalTimeFields(item, fieldNames); - return ES.TimeFromFields(calendar, fields, constructor, overflow); - } - - let { hour, minute, second, millisecond, microsecond, nanosecond, calendar } = ES.ParseTemporalTimeString( - ES.ToString(item) - ); + calendar = item.calendar; + if (calendar) { + calendar = ES.ToTemporalCalendar(calendar); + if (ES.CalendarToString(calendar) !== 'iso8601') { + throw new RangeError('PlainTime can only have iso8601 calendar'); + } + } + ({ hour, minute, second, millisecond, microsecond, nanosecond } = ES.ToTemporalTimeRecord(item)); + } else { + ({ hour, minute, second, millisecond, microsecond, nanosecond, calendar } = ES.ParseTemporalTimeString( + ES.ToString(item) + )); + if (calendar !== undefined && calendar !== 'iso8601') { + throw new RangeError('PlainTime can only have iso8601 calendar'); + } + } ({ hour, minute, second, millisecond, microsecond, nanosecond } = ES.RegulateTime( hour, minute, @@ -1160,9 +1142,7 @@ export const ES = ObjectAssign({}, ES2020, { nanosecond, overflow )); - if (calendar === undefined) calendar = new (GetIntrinsic('%Temporal.ISO8601Calendar%'))(); - calendar = ES.ToTemporalCalendar(calendar); - let result = new constructor(hour, minute, second, millisecond, microsecond, nanosecond, calendar); + let result = new constructor(hour, minute, second, millisecond, microsecond, nanosecond); if (!ES.IsTemporalTime(result)) throw new TypeError('invalid result'); return result; }, @@ -1372,11 +1352,6 @@ export const ES = ObjectAssign({}, ES2020, { throw new RangeError('irreconcilable calendars'); } }, - TimeFromFields: (calendar, fields, constructor, overflow = 'constrain') => { - const result = calendar.timeFromFields(fields, { overflow }, constructor); - if (!ES.IsTemporalTime(result)) throw new TypeError('invalid result'); - return result; - }, DateFromFields: (calendar, fields, constructor, overflow = 'constrain') => { const result = calendar.dateFromFields(fields, { overflow }, constructor); if (!ES.IsTemporalDate(result)) throw new TypeError('invalid result'); @@ -2529,12 +2504,19 @@ export const ES = ObjectAssign({}, ES2020, { largestUnit ) => { const TemporalDate = GetIntrinsic('%Temporal.PlainDate%'); - const TemporalTime = GetIntrinsic('%Temporal.PlainTime%'); - const time1 = new TemporalTime(h1, min1, s1, ms1, µs1, ns1, calendar); - const time2 = new TemporalTime(h2, min2, s2, ms2, µs2, ns2, calendar); - let { days: deltaDays, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = calendar.timeUntil( - time1, - time2 + let { deltaDays, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = ES.DifferenceTime( + h1, + min1, + s1, + ms1, + µs1, + ns1, + h2, + min2, + s2, + ms2, + µs2, + ns2 ); ({ year: y1, month: mon1, day: d1 } = ES.BalanceDate(y1, mon1, d1 + deltaDays)); const date1 = new TemporalDate(y1, mon1, d1, calendar); diff --git a/polyfill/lib/now.mjs b/polyfill/lib/now.mjs index 8a14981cd1..b679963039 100644 --- a/polyfill/lib/now.mjs +++ b/polyfill/lib/now.mjs @@ -8,7 +8,6 @@ export const now = { plainDateTimeISO, plainDate, plainDateISO, - plainTime, plainTimeISO, timeZone, zonedDateTime, @@ -49,9 +48,6 @@ function plainDate(calendarLike, temporalTimeZoneLike = timeZone()) { function plainDateISO(temporalTimeZoneLike = timeZone()) { return ES.TemporalDateTimeToDate(plainDateTimeISO(temporalTimeZoneLike)); } -function plainTime(calendarLike, temporalTimeZoneLike = timeZone()) { - return ES.TemporalDateTimeToTime(plainDateTime(calendarLike, temporalTimeZoneLike)); -} function plainTimeISO(temporalTimeZoneLike = timeZone()) { return ES.TemporalDateTimeToTime(plainDateTimeISO(temporalTimeZoneLike)); } diff --git a/polyfill/lib/plaindate.mjs b/polyfill/lib/plaindate.mjs index 3b9ad4d6b0..90fd7ee9ed 100644 --- a/polyfill/lib/plaindate.mjs +++ b/polyfill/lib/plaindate.mjs @@ -310,10 +310,10 @@ export class PlainDate { const year = GetSlot(this, ISO_YEAR); const month = GetSlot(this, ISO_MONTH); const day = GetSlot(this, ISO_DAY); - const dateCalendar = GetSlot(this, CALENDAR); + const calendar = GetSlot(this, CALENDAR); const DateTime = GetIntrinsic('%Temporal.PlainDateTime%'); - if (temporalTime === undefined) return new DateTime(year, month, day, 0, 0, 0, 0, 0, 0, dateCalendar); + if (temporalTime === undefined) return new DateTime(year, month, day, 0, 0, 0, 0, 0, 0, calendar); temporalTime = ES.ToTemporalTime(temporalTime, GetIntrinsic('%Temporal.PlainTime%')); const hour = GetSlot(temporalTime, ISO_HOUR); @@ -322,9 +322,7 @@ export class PlainDate { const millisecond = GetSlot(temporalTime, ISO_MILLISECOND); const microsecond = GetSlot(temporalTime, ISO_MICROSECOND); const nanosecond = GetSlot(temporalTime, ISO_NANOSECOND); - const timeCalendar = GetSlot(temporalTime, CALENDAR); - const calendar = ES.ConsolidateCalendars(dateCalendar, timeCalendar); return new DateTime(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, calendar); } toZonedDateTime(item) { @@ -348,7 +346,6 @@ export class PlainDate { const day = GetSlot(this, ISO_DAY); const calendar = GetSlot(this, CALENDAR); - // TODO: use start of day in calendar. let hour = 0, minute = 0, second = 0, @@ -363,7 +360,6 @@ export class PlainDate { millisecond = GetSlot(temporalTime, ISO_MILLISECOND); microsecond = GetSlot(temporalTime, ISO_MICROSECOND); nanosecond = GetSlot(temporalTime, ISO_NANOSECOND); - // TODO: verify calendars match } const PlainDateTime = GetIntrinsic('%Temporal.PlainDateTime%'); diff --git a/polyfill/lib/plaindatetime.mjs b/polyfill/lib/plaindatetime.mjs index b3fd9292f2..b9213375f0 100644 --- a/polyfill/lib/plaindatetime.mjs +++ b/polyfill/lib/plaindatetime.mjs @@ -129,27 +129,27 @@ export class PlainDateTime { } get hour() { if (!ES.IsTemporalDateTime(this)) throw new TypeError('invalid receiver'); - return GetSlot(this, CALENDAR).hour(this); + return GetSlot(this, ISO_HOUR); } get minute() { if (!ES.IsTemporalDateTime(this)) throw new TypeError('invalid receiver'); - return GetSlot(this, CALENDAR).minute(this); + return GetSlot(this, ISO_MINUTE); } get second() { if (!ES.IsTemporalDateTime(this)) throw new TypeError('invalid receiver'); - return GetSlot(this, CALENDAR).second(this); + return GetSlot(this, ISO_SECOND); } get millisecond() { if (!ES.IsTemporalDateTime(this)) throw new TypeError('invalid receiver'); - return GetSlot(this, CALENDAR).millisecond(this); + return GetSlot(this, ISO_MILLISECOND); } get microsecond() { if (!ES.IsTemporalDateTime(this)) throw new TypeError('invalid receiver'); - return GetSlot(this, CALENDAR).microsecond(this); + return GetSlot(this, ISO_MICROSECOND); } get nanosecond() { if (!ES.IsTemporalDateTime(this)) throw new TypeError('invalid receiver'); - return GetSlot(this, CALENDAR).nanosecond(this); + return GetSlot(this, ISO_NANOSECOND); } get dayOfWeek() { if (!ES.IsTemporalDateTime(this)) throw new TypeError('invalid receiver'); @@ -248,10 +248,10 @@ export class PlainDateTime { const year = GetSlot(this, ISO_YEAR); const month = GetSlot(this, ISO_MONTH); const day = GetSlot(this, ISO_DAY); - const dateCalendar = GetSlot(this, CALENDAR); + const calendar = GetSlot(this, CALENDAR); const Construct = ES.SpeciesConstructor(this, PlainDateTime); - if (temporalTime === undefined) return new Construct(year, month, day, 0, 0, 0, 0, 0, 0, dateCalendar); + if (temporalTime === undefined) return new Construct(year, month, day, 0, 0, 0, 0, 0, 0, calendar); temporalTime = ES.ToTemporalTime(temporalTime, GetIntrinsic('%Temporal.PlainTime%')); const hour = GetSlot(temporalTime, ISO_HOUR); @@ -260,9 +260,7 @@ export class PlainDateTime { const millisecond = GetSlot(temporalTime, ISO_MILLISECOND); const microsecond = GetSlot(temporalTime, ISO_MICROSECOND); const nanosecond = GetSlot(temporalTime, ISO_NANOSECOND); - const timeCalendar = GetSlot(temporalTime, CALENDAR); - const calendar = ES.ConsolidateCalendars(dateCalendar, timeCalendar); return new Construct(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, calendar); } withPlainDate(temporalDate) { @@ -272,7 +270,7 @@ export class PlainDateTime { const year = GetSlot(temporalDate, ISO_YEAR); const month = GetSlot(temporalDate, ISO_MONTH); const day = GetSlot(temporalDate, ISO_DAY); - const dateCalendar = GetSlot(temporalDate, CALENDAR); + let calendar = GetSlot(temporalDate, CALENDAR); const hour = GetSlot(this, ISO_HOUR); const minute = GetSlot(this, ISO_MINUTE); @@ -280,9 +278,8 @@ export class PlainDateTime { const millisecond = GetSlot(this, ISO_MILLISECOND); const microsecond = GetSlot(this, ISO_MICROSECOND); const nanosecond = GetSlot(this, ISO_NANOSECOND); - const timeCalendar = GetSlot(this, CALENDAR); - const calendar = ES.ConsolidateCalendars(dateCalendar, timeCalendar); + calendar = ES.ConsolidateCalendars(GetSlot(this, CALENDAR), calendar); const Construct = ES.SpeciesConstructor(this, PlainDateTime); return new Construct(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, calendar); } diff --git a/polyfill/lib/plaintime.mjs b/polyfill/lib/plaintime.mjs index b038a44081..93c312c48e 100644 --- a/polyfill/lib/plaintime.mjs +++ b/polyfill/lib/plaintime.mjs @@ -24,7 +24,7 @@ import { const ObjectAssign = Object.assign; -function TemporalTimeToString(time, precision, showCalendar = 'auto', options = undefined) { +function TemporalTimeToString(time, precision, options = undefined) { let hour = GetSlot(time, ISO_HOUR); let minute = GetSlot(time, ISO_MINUTE); let second = GetSlot(time, ISO_SECOND); @@ -50,27 +50,17 @@ function TemporalTimeToString(time, precision, showCalendar = 'auto', options = hour = ES.ISODateTimePartString(hour); minute = ES.ISODateTimePartString(minute); const seconds = ES.FormatSecondsStringPart(second, millisecond, microsecond, nanosecond, precision); - const calendar = ES.FormatCalendarAnnotation(GetSlot(time, CALENDAR), showCalendar); - return `${hour}:${minute}${seconds}${calendar}`; + return `${hour}:${minute}${seconds}`; } export class PlainTime { - constructor( - isoHour = 0, - isoMinute = 0, - isoSecond = 0, - isoMillisecond = 0, - isoMicrosecond = 0, - isoNanosecond = 0, - calendar = GetISO8601Calendar() - ) { + constructor(isoHour = 0, isoMinute = 0, isoSecond = 0, isoMillisecond = 0, isoMicrosecond = 0, isoNanosecond = 0) { isoHour = ES.ToInteger(isoHour); isoMinute = ES.ToInteger(isoMinute); isoSecond = ES.ToInteger(isoSecond); isoMillisecond = ES.ToInteger(isoMillisecond); isoMicrosecond = ES.ToInteger(isoMicrosecond); isoNanosecond = ES.ToInteger(isoNanosecond); - calendar = ES.ToTemporalCalendar(calendar); ES.RejectTime(isoHour, isoMinute, isoSecond, isoMillisecond, isoMicrosecond, isoNanosecond); CreateSlots(this); @@ -80,7 +70,6 @@ export class PlainTime { SetSlot(this, ISO_MILLISECOND, isoMillisecond); SetSlot(this, ISO_MICROSECOND, isoMicrosecond); SetSlot(this, ISO_NANOSECOND, isoNanosecond); - SetSlot(this, CALENDAR, calendar); if (typeof __debug__ !== 'undefined' && __debug__) { Object.defineProperty(this, '_repr_', { @@ -94,31 +83,31 @@ export class PlainTime { get calendar() { if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver'); - return GetSlot(this, CALENDAR); + return GetISO8601Calendar(); } get hour() { if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver'); - return GetSlot(this, CALENDAR).hour(this); + return GetSlot(this, ISO_HOUR); } get minute() { if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver'); - return GetSlot(this, CALENDAR).minute(this); + return GetSlot(this, ISO_MINUTE); } get second() { if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver'); - return GetSlot(this, CALENDAR).second(this); + return GetSlot(this, ISO_SECOND); } get millisecond() { if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver'); - return GetSlot(this, CALENDAR).millisecond(this); + return GetSlot(this, ISO_MILLISECOND); } get microsecond() { if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver'); - return GetSlot(this, CALENDAR).microsecond(this); + return GetSlot(this, ISO_MICROSECOND); } get nanosecond() { if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver'); - return GetSlot(this, CALENDAR).nanosecond(this); + return GetSlot(this, ISO_NANOSECOND); } with(temporalTimeLike, options = undefined) { @@ -136,8 +125,7 @@ export class PlainTime { options = ES.NormalizeOptionsObject(options); const overflow = ES.ToTemporalOverflow(options); - const calendar = GetSlot(this, CALENDAR); - const fieldNames = ES.CalendarFields(calendar, [ + const props = ES.ToPartialRecord(temporalTimeLike, [ 'hour', 'microsecond', 'millisecond', @@ -145,29 +133,22 @@ export class PlainTime { 'nanosecond', 'second' ]); - const props = ES.ToPartialRecord(temporalTimeLike, fieldNames); if (!props) { throw new TypeError('invalid time-like'); } - const fields = ES.ToTemporalTimeFields(this, fieldNames); - ObjectAssign(fields, props); - - const Construct = ES.SpeciesConstructor(this, PlainTime); - return ES.TimeFromFields(calendar, fields, Construct, overflow); - } - withCalendar(calendar) { - if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver'); - calendar = ES.ToTemporalCalendar(calendar); + const fields = ES.ToTemporalTimeRecord(this); + let { hour, minute, second, millisecond, microsecond, nanosecond } = ObjectAssign(fields, props); + ({ hour, minute, second, millisecond, microsecond, nanosecond } = ES.RegulateTime( + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + overflow + )); const Construct = ES.SpeciesConstructor(this, PlainTime); - const result = new Construct( - GetSlot(this, ISO_HOUR), - GetSlot(this, ISO_MINUTE), - GetSlot(this, ISO_SECOND), - GetSlot(this, ISO_MILLISECOND), - GetSlot(this, ISO_MICROSECOND), - GetSlot(this, ISO_NANOSECOND), - calendar - ); + const result = new Construct(hour, minute, second, millisecond, microsecond, nanosecond); if (!ES.IsTemporalTime(result)) throw new TypeError('invalid result'); return result; } @@ -176,44 +157,86 @@ export class PlainTime { const duration = ES.ToLimitedTemporalDuration(temporalDurationLike); const { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = duration; ES.RejectDurationSign(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds); + options = ES.NormalizeOptionsObject(options); + const overflow = ES.ToTemporalOverflow(options); + let hour = GetSlot(this, ISO_HOUR); + let minute = GetSlot(this, ISO_MINUTE); + let second = GetSlot(this, ISO_SECOND); + let millisecond = GetSlot(this, ISO_MILLISECOND); + let microsecond = GetSlot(this, ISO_MICROSECOND); + let nanosecond = GetSlot(this, ISO_NANOSECOND); + ({ hour, minute, second, millisecond, microsecond, nanosecond } = ES.AddTime( + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + hours, + minutes, + seconds, + milliseconds, + microseconds, + nanoseconds + )); + ({ hour, minute, second, millisecond, microsecond, nanosecond } = ES.RegulateTime( + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + overflow + )); const Construct = ES.SpeciesConstructor(this, PlainTime); - const result = GetSlot(this, CALENDAR).timeAdd(this, duration, options, Construct); + const result = new Construct(hour, minute, second, millisecond, microsecond, nanosecond); if (!ES.IsTemporalTime(result)) throw new TypeError('invalid result'); return result; } subtract(temporalDurationLike, options = undefined) { if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver'); let duration = ES.ToLimitedTemporalDuration(temporalDurationLike); - duration = { - years: -duration.years, - months: -duration.months, - weeks: -duration.weeks, - days: -duration.days, - hours: -duration.hours, - minutes: -duration.minutes, - seconds: -duration.seconds, - milliseconds: -duration.milliseconds, - microseconds: -duration.microseconds, - nanoseconds: -duration.nanoseconds - }; const { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = duration; ES.RejectDurationSign(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds); + options = ES.NormalizeOptionsObject(options); + const overflow = ES.ToTemporalOverflow(options); + let hour = GetSlot(this, ISO_HOUR); + let minute = GetSlot(this, ISO_MINUTE); + let second = GetSlot(this, ISO_SECOND); + let millisecond = GetSlot(this, ISO_MILLISECOND); + let microsecond = GetSlot(this, ISO_MICROSECOND); + let nanosecond = GetSlot(this, ISO_NANOSECOND); + ({ hour, minute, second, millisecond, microsecond, nanosecond } = ES.AddTime( + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + -hours, + -minutes, + -seconds, + -milliseconds, + -microseconds, + -nanoseconds + )); + ({ hour, minute, second, millisecond, microsecond, nanosecond } = ES.RegulateTime( + hour, + minute, + second, + millisecond, + microsecond, + nanosecond, + overflow + )); const Construct = ES.SpeciesConstructor(this, PlainTime); - const result = GetSlot(this, CALENDAR).timeAdd(this, duration, options, Construct); + const result = new Construct(hour, minute, second, millisecond, microsecond, nanosecond); if (!ES.IsTemporalTime(result)) throw new TypeError('invalid result'); return result; } until(other, options = undefined) { if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver'); other = ES.ToTemporalTime(other, PlainTime); - const calendar = GetSlot(this, CALENDAR); - const otherCalendar = GetSlot(other, CALENDAR); - const calendarId = ES.CalendarToString(calendar); - const otherCalendarId = ES.CalendarToString(otherCalendar); - if (calendarId !== otherCalendarId) { - throw new RangeError(`cannot compute difference between times of ${calendarId} and ${otherCalendarId} calendars`); - } - options = ES.NormalizeOptionsObject(options); const largestUnit = ES.ToLargestTemporalUnit(options, 'hours', ['years', 'months', 'weeks', 'days']); const smallestUnit = ES.ToSmallestTemporalDurationUnit(options, 'nanoseconds'); @@ -228,8 +251,20 @@ export class PlainTime { nanoseconds: 1000 }; const roundingIncrement = ES.ToTemporalRoundingIncrement(options, maximumIncrements[smallestUnit], false); - - let { hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = calendar.timeUntil(this, other); + let { hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = ES.DifferenceTime( + GetSlot(this, ISO_HOUR), + GetSlot(this, ISO_MINUTE), + GetSlot(this, ISO_SECOND), + GetSlot(this, ISO_MILLISECOND), + GetSlot(this, ISO_MICROSECOND), + GetSlot(this, ISO_NANOSECOND), + GetSlot(other, ISO_HOUR), + GetSlot(other, ISO_MINUTE), + GetSlot(other, ISO_SECOND), + GetSlot(other, ISO_MILLISECOND), + GetSlot(other, ISO_MICROSECOND), + GetSlot(other, ISO_NANOSECOND) + ); ({ hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = ES.RoundDuration( 0, 0, @@ -261,14 +296,6 @@ export class PlainTime { since(other, options = undefined) { if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver'); other = ES.ToTemporalTime(other, PlainTime); - const calendar = GetSlot(this, CALENDAR); - const otherCalendar = GetSlot(other, CALENDAR); - const calendarId = ES.CalendarToString(calendar); - const otherCalendarId = ES.CalendarToString(otherCalendar); - if (calendarId !== otherCalendarId) { - throw new RangeError(`cannot compute difference between times of ${calendarId} and ${otherCalendarId} calendars`); - } - options = ES.NormalizeOptionsObject(options); const largestUnit = ES.ToLargestTemporalUnit(options, 'hours', ['years', 'months', 'weeks', 'days']); const smallestUnit = ES.ToSmallestTemporalDurationUnit(options, 'nanoseconds'); @@ -283,8 +310,20 @@ export class PlainTime { nanoseconds: 1000 }; const roundingIncrement = ES.ToTemporalRoundingIncrement(options, maximumIncrements[smallestUnit], false); - - let { hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = calendar.timeUntil(other, this); + let { hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = ES.DifferenceTime( + GetSlot(other, ISO_HOUR), + GetSlot(other, ISO_MINUTE), + GetSlot(other, ISO_SECOND), + GetSlot(other, ISO_MILLISECOND), + GetSlot(other, ISO_MICROSECOND), + GetSlot(other, ISO_NANOSECOND), + GetSlot(this, ISO_HOUR), + GetSlot(this, ISO_MINUTE), + GetSlot(this, ISO_SECOND), + GetSlot(this, ISO_MILLISECOND), + GetSlot(this, ISO_MICROSECOND), + GetSlot(this, ISO_NANOSECOND) + ); ({ hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = ES.RoundDuration( 0, 0, @@ -374,8 +413,7 @@ export class PlainTime { options = ES.NormalizeOptionsObject(options); const { precision, unit, increment } = ES.ToSecondsStringPrecision(options); const roundingMode = ES.ToTemporalRoundingMode(options, 'trunc'); - const showCalendar = ES.ToShowCalendarOption(options); - return TemporalTimeToString(this, precision, showCalendar, { unit, increment, roundingMode }); + return TemporalTimeToString(this, precision, { unit, increment, roundingMode }); } toJSON() { if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver'); @@ -396,7 +434,7 @@ export class PlainTime { const year = GetSlot(temporalDate, ISO_YEAR); const month = GetSlot(temporalDate, ISO_MONTH); const day = GetSlot(temporalDate, ISO_DAY); - const dateCalendar = GetSlot(temporalDate, CALENDAR); + const calendar = GetSlot(temporalDate, CALENDAR); const hour = GetSlot(this, ISO_HOUR); const minute = GetSlot(this, ISO_MINUTE); @@ -404,9 +442,7 @@ export class PlainTime { const millisecond = GetSlot(this, ISO_MILLISECOND); const microsecond = GetSlot(this, ISO_MICROSECOND); const nanosecond = GetSlot(this, ISO_NANOSECOND); - const timeCalendar = GetSlot(this, CALENDAR); - const calendar = ES.ConsolidateCalendars(dateCalendar, timeCalendar); const DateTime = GetIntrinsic('%Temporal.PlainDateTime%'); return new DateTime(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, calendar); } @@ -432,7 +468,6 @@ export class PlainTime { const year = GetSlot(temporalDate, ISO_YEAR); const month = GetSlot(temporalDate, ISO_MONTH); const day = GetSlot(temporalDate, ISO_DAY); - // TODO: verify calendars match const calendar = GetSlot(temporalDate, CALENDAR); const hour = GetSlot(this, ISO_HOUR); const minute = GetSlot(this, ISO_MINUTE); @@ -459,24 +494,15 @@ export class PlainTime { return new ZonedDateTime(GetSlot(instant, EPOCHNANOSECONDS), timeZone, calendar); } getFields() { - if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver'); - const calendar = GetSlot(this, CALENDAR); - const fieldNames = ES.CalendarFields(calendar, [ - 'hour', - 'microsecond', - 'millisecond', - 'minute', - 'nanosecond', - 'second' - ]); - const fields = ES.ToTemporalTimeFields(this, fieldNames); - fields.calendar = GetSlot(this, CALENDAR); + const fields = ES.ToTemporalTimeRecord(this); + if (!fields) throw new TypeError('invalid receiver'); + fields.calendar = GetISO8601Calendar(); return fields; } getISOFields() { if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver'); return { - calendar: GetSlot(this, CALENDAR), + calendar: GetISO8601Calendar(), isoHour: GetSlot(this, ISO_HOUR), isoMicrosecond: GetSlot(this, ISO_MICROSECOND), isoMillisecond: GetSlot(this, ISO_MILLISECOND), @@ -496,8 +522,7 @@ export class PlainTime { const millisecond = GetSlot(item, ISO_MILLISECOND); const microsecond = GetSlot(item, ISO_MICROSECOND); const nanosecond = GetSlot(item, ISO_NANOSECOND); - const calendar = GetSlot(item, CALENDAR); - const result = new this(hour, minute, second, millisecond, microsecond, nanosecond, calendar); + const result = new this(hour, minute, second, millisecond, microsecond, nanosecond); if (!ES.IsTemporalTime(result)) throw new TypeError('invalid result'); return result; } @@ -511,7 +536,7 @@ export class PlainTime { const val2 = GetSlot(two, slot); if (val1 !== val2) return ES.ComparisonResult(val1 - val2); } - return ES.CalendarCompare(GetSlot(one, CALENDAR), GetSlot(two, CALENDAR)); + return 0; } } diff --git a/polyfill/lib/zoneddatetime.mjs b/polyfill/lib/zoneddatetime.mjs index e18605f2b2..f1eb1df596 100644 --- a/polyfill/lib/zoneddatetime.mjs +++ b/polyfill/lib/zoneddatetime.mjs @@ -251,8 +251,7 @@ export class ZonedDateTime { const year = GetSlot(temporalDate, ISO_YEAR); const month = GetSlot(temporalDate, ISO_MONTH); const day = GetSlot(temporalDate, ISO_DAY); - const dateCalendar = GetSlot(temporalDate, CALENDAR); - const timeCalendar = GetSlot(this, CALENDAR); + let calendar = GetSlot(temporalDate, CALENDAR); const thisDt = dateTime(this); const hour = GetSlot(thisDt, ISO_HOUR); const minute = GetSlot(thisDt, ISO_MINUTE); @@ -261,7 +260,7 @@ export class ZonedDateTime { const microsecond = GetSlot(thisDt, ISO_MICROSECOND); const nanosecond = GetSlot(thisDt, ISO_NANOSECOND); - const calendar = ES.ConsolidateCalendars(dateCalendar, timeCalendar); + calendar = ES.ConsolidateCalendars(GetSlot(this, CALENDAR), calendar); const timeZone = GetSlot(this, TIME_ZONE); const PlainDateTime = GetIntrinsic('%Temporal.PlainDateTime%'); const dt = new PlainDateTime( @@ -290,16 +289,14 @@ export class ZonedDateTime { const year = GetSlot(thisDt, ISO_YEAR); const month = GetSlot(thisDt, ISO_MONTH); const day = GetSlot(thisDt, ISO_DAY); - const dateCalendar = GetSlot(this, CALENDAR); + const calendar = GetSlot(this, CALENDAR); const hour = GetSlot(temporalTime, ISO_HOUR); const minute = GetSlot(temporalTime, ISO_MINUTE); const second = GetSlot(temporalTime, ISO_SECOND); const millisecond = GetSlot(temporalTime, ISO_MILLISECOND); const microsecond = GetSlot(temporalTime, ISO_MICROSECOND); const nanosecond = GetSlot(temporalTime, ISO_NANOSECOND); - const timeCalendar = GetSlot(temporalTime, CALENDAR); - const calendar = ES.ConsolidateCalendars(dateCalendar, timeCalendar); const timeZone = GetSlot(this, TIME_ZONE); const PlainDateTime = GetIntrinsic('%Temporal.PlainDateTime%'); const dt = new PlainDateTime( diff --git a/polyfill/test/PlainTime/prototype/withCalendar/basic.js b/polyfill/test/PlainTime/prototype/withCalendar/basic.js deleted file mode 100644 index 57c5cdc5e7..0000000000 --- a/polyfill/test/PlainTime/prototype/withCalendar/basic.js +++ /dev/null @@ -1,18 +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.withcalendar ----*/ - -const calendar = Temporal.Calendar.from("iso8601"); -const instance = Temporal.PlainTime.from("12:34:56.987654321"); -const result = instance.withCalendar(calendar); -assert.sameValue(result.hour, 12, "hour result"); -assert.sameValue(result.minute, 34, "minute result"); -assert.sameValue(result.second, 56, "second result"); -assert.sameValue(result.millisecond, 987, "millisecond result"); -assert.sameValue(result.microsecond, 654, "microsecond result"); -assert.sameValue(result.nanosecond, 321, "nanosecond result"); -assert.sameValue(result.calendar, calendar, "calendar result"); -assert.sameValue(Object.getPrototypeOf(result), Temporal.PlainTime.prototype); diff --git a/polyfill/test/PlainTime/prototype/withCalendar/calendar-object.js b/polyfill/test/PlainTime/prototype/withCalendar/calendar-object.js deleted file mode 100644 index 771d148c64..0000000000 --- a/polyfill/test/PlainTime/prototype/withCalendar/calendar-object.js +++ /dev/null @@ -1,14 +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.withcalendar ----*/ - -Temporal.Calendar.from = function() { - throw new Test262Error("Should not call Calendar.from"); -}; -const calendar = {}; -const instance = Temporal.PlainTime.from("12:34:56.987654321"); -const result = instance.withCalendar(calendar); -assert.sameValue(result.calendar, calendar, "calendar result"); diff --git a/polyfill/test/PlainTime/prototype/withCalendar/calendar-primitive.js b/polyfill/test/PlainTime/prototype/withCalendar/calendar-primitive.js deleted file mode 100644 index ce8007f9ff..0000000000 --- a/polyfill/test/PlainTime/prototype/withCalendar/calendar-primitive.js +++ /dev/null @@ -1,36 +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.withcalendar ----*/ - -const values = [ - [null, "null"], - [true, "true"], - ["iso8601", "iso8601"], - [2020, "2020"], - [2n, "2"], -]; - -const instance = Temporal.PlainTime.from("12:34:56.987654321"); - -const calendar = Temporal.Calendar.from("iso8601"); -for (const [input, output] of values) { - let called = 0; - Temporal.Calendar.from = function(argument) { - ++called; - assert.sameValue(argument, output); - return calendar; - }; - - const result = instance.withCalendar(input); - assert.sameValue(called, 1); - assert.sameValue(result.calendar, calendar); -} - -Temporal.Calendar.from = function() { - throw new Test262Error("Should not call Calendar.from"); -}; - -assert.throws(TypeError, () => instance.withCalendar(Symbol())); diff --git a/polyfill/test/PlainTime/prototype/withCalendar/length.js b/polyfill/test/PlainTime/prototype/withCalendar/length.js deleted file mode 100644 index 3d3004d466..0000000000 --- a/polyfill/test/PlainTime/prototype/withCalendar/length.js +++ /dev/null @@ -1,23 +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.withcalendar -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] ----*/ - -verifyProperty(Temporal.PlainTime.prototype.withCalendar, "length", { - value: 1, - writable: false, - enumerable: false, - configurable: true, -}); diff --git a/polyfill/test/PlainTime/prototype/withCalendar/subclass-constructor-not-object.js b/polyfill/test/PlainTime/prototype/withCalendar/subclass-constructor-not-object.js deleted file mode 100644 index 3729b223dd..0000000000 --- a/polyfill/test/PlainTime/prototype/withCalendar/subclass-constructor-not-object.js +++ /dev/null @@ -1,19 +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.withcalendar ----*/ - -function check(value, description) { - const time = Temporal.PlainTime.from({ hour: 12, minute: 34, second: 56, millisecond: 987, microsecond: 654, nanosecond: 321 }); - time.constructor = value; - assert.throws(TypeError, () => time.withCalendar("iso8601"), description); -} - -check(null, "null"); -check(true, "true"); -check("test", "string"); -check(Symbol(), "Symbol"); -check(7, "number"); -check(7n, "bigint"); diff --git a/polyfill/test/PlainTime/prototype/withCalendar/subclass-constructor-throws.js b/polyfill/test/PlainTime/prototype/withCalendar/subclass-constructor-throws.js deleted file mode 100644 index c43e00596d..0000000000 --- a/polyfill/test/PlainTime/prototype/withCalendar/subclass-constructor-throws.js +++ /dev/null @@ -1,17 +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.withcalendar ----*/ - -function CustomError() {} - -const time = Temporal.PlainTime.from({ hour: 12, minute: 34, second: 56, millisecond: 987, microsecond: 654, nanosecond: 321 }); -Object.defineProperty(time, "constructor", { - get() { - throw new CustomError(); - } -}); - -assert.throws(CustomError, () => time.withCalendar("iso8601")); diff --git a/polyfill/test/PlainTime/prototype/withCalendar/subclass-constructor-undefined.js b/polyfill/test/PlainTime/prototype/withCalendar/subclass-constructor-undefined.js deleted file mode 100644 index 7468680848..0000000000 --- a/polyfill/test/PlainTime/prototype/withCalendar/subclass-constructor-undefined.js +++ /dev/null @@ -1,34 +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.withcalendar -includes: [compareArray.js] ----*/ - -let called = 0; - -class MyTime extends Temporal.PlainTime { - constructor(hour, minute, second, millisecond, microsecond, nanosecond) { - assert.compareArray([hour, minute, second, millisecond, microsecond, nanosecond], [12, 34, 56, 987, 654, 321], "constructor arguments"); - ++called; - super(hour, minute, second, millisecond, microsecond, nanosecond); - } -} - -const instance = MyTime.from("12:34:56.987654321"); -assert.sameValue(called, 1); - -MyTime.prototype.constructor = undefined; - -const calendar = Temporal.Calendar.from("iso8601"); -const result = instance.withCalendar(calendar); -assert.sameValue(result.hour, 12, "hour result"); -assert.sameValue(result.minute, 34, "minute result"); -assert.sameValue(result.second, 56, "second result"); -assert.sameValue(result.millisecond, 987, "millisecond result"); -assert.sameValue(result.microsecond, 654, "microsecond result"); -assert.sameValue(result.nanosecond, 321, "nanosecond result"); -assert.sameValue(result.calendar, calendar, "calendar result"); -assert.sameValue(called, 1); -assert.sameValue(Object.getPrototypeOf(result), Temporal.PlainTime.prototype); diff --git a/polyfill/test/PlainTime/prototype/withCalendar/subclass-invalid-result.js b/polyfill/test/PlainTime/prototype/withCalendar/subclass-invalid-result.js deleted file mode 100644 index 9f003ecc6e..0000000000 --- a/polyfill/test/PlainTime/prototype/withCalendar/subclass-invalid-result.js +++ /dev/null @@ -1,26 +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.withcalendar -features: [Symbol.species] ----*/ - -function check(value, description) { - const time = Temporal.PlainTime.from({ hour: 12, minute: 34, second: 56, millisecond: 987, microsecond: 654, nanosecond: 321 }); - time.constructor = { - [Symbol.species]: function() { - return value; - }, - }; - assert.throws(TypeError, () => time.withCalendar("iso8601"), description); -} - -check(undefined, "undefined"); -check(null, "null"); -check(true, "true"); -check("test", "string"); -check(Symbol(), "Symbol"); -check(7, "number"); -check(7n, "bigint"); -check({}, "plain object"); diff --git a/polyfill/test/PlainTime/prototype/withCalendar/subclass-species-not-constructor.js b/polyfill/test/PlainTime/prototype/withCalendar/subclass-species-not-constructor.js deleted file mode 100644 index e1591f196a..0000000000 --- a/polyfill/test/PlainTime/prototype/withCalendar/subclass-species-not-constructor.js +++ /dev/null @@ -1,22 +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.withcalendar -features: [Symbol.species] ----*/ - -function check(value, description) { - const time = Temporal.PlainTime.from({ hour: 12, minute: 34, second: 56, millisecond: 987, microsecond: 654, nanosecond: 321 }); - time.constructor = { - [Symbol.species]: value, - }; - assert.throws(TypeError, () => time.withCalendar("iso8601"), description); -} - -check(true, "true"); -check("test", "string"); -check(Symbol(), "Symbol"); -check(7, "number"); -check(7n, "bigint"); -check({}, "plain object"); diff --git a/polyfill/test/PlainTime/prototype/withCalendar/subclass-species-null.js b/polyfill/test/PlainTime/prototype/withCalendar/subclass-species-null.js deleted file mode 100644 index fb6adf22db..0000000000 --- a/polyfill/test/PlainTime/prototype/withCalendar/subclass-species-null.js +++ /dev/null @@ -1,37 +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.withcalendar -includes: [compareArray.js] -features: [Symbol.species] ----*/ - -let called = 0; - -class MyTime extends Temporal.PlainTime { - constructor(hour, minute, second, millisecond, microsecond, nanosecond) { - assert.compareArray([hour, minute, second, millisecond, microsecond, nanosecond], [12, 34, 56, 987, 654, 321], "constructor arguments"); - ++called; - super(hour, minute, second, millisecond, microsecond, nanosecond); - } -} - -const instance = MyTime.from("12:34:56.987654321"); -assert.sameValue(called, 1); - -MyTime.prototype.constructor = { - [Symbol.species]: null, -}; - -const calendar = Temporal.Calendar.from("iso8601"); -const result = instance.withCalendar(calendar); -assert.sameValue(result.hour, 12, "hour result"); -assert.sameValue(result.minute, 34, "minute result"); -assert.sameValue(result.second, 56, "second result"); -assert.sameValue(result.millisecond, 987, "millisecond result"); -assert.sameValue(result.microsecond, 654, "microsecond result"); -assert.sameValue(result.nanosecond, 321, "nanosecond result"); -assert.sameValue(result.calendar, calendar, "calendar result"); -assert.sameValue(called, 1); -assert.sameValue(Object.getPrototypeOf(result), Temporal.PlainTime.prototype); diff --git a/polyfill/test/PlainTime/prototype/withCalendar/subclass-species-throws.js b/polyfill/test/PlainTime/prototype/withCalendar/subclass-species-throws.js deleted file mode 100644 index 02d0323317..0000000000 --- a/polyfill/test/PlainTime/prototype/withCalendar/subclass-species-throws.js +++ /dev/null @@ -1,18 +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.withcalendar -features: [Symbol.species] ----*/ - -function CustomError() {} - -const time = Temporal.PlainTime.from({ hour: 12, minute: 34, second: 56, millisecond: 987, microsecond: 654, nanosecond: 321 }); -time.constructor = { - get [Symbol.species]() { - throw new CustomError(); - }, -}; - -assert.throws(CustomError, () => time.withCalendar("iso8601")); diff --git a/polyfill/test/PlainTime/prototype/withCalendar/subclass-species-undefined.js b/polyfill/test/PlainTime/prototype/withCalendar/subclass-species-undefined.js deleted file mode 100644 index ef827208e5..0000000000 --- a/polyfill/test/PlainTime/prototype/withCalendar/subclass-species-undefined.js +++ /dev/null @@ -1,37 +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.withcalendar -includes: [compareArray.js] -features: [Symbol.species] ----*/ - -let called = 0; - -class MyTime extends Temporal.PlainTime { - constructor(hour, minute, second, millisecond, microsecond, nanosecond) { - assert.compareArray([hour, minute, second, millisecond, microsecond, nanosecond], [12, 34, 56, 987, 654, 321], "constructor arguments"); - ++called; - super(hour, minute, second, millisecond, microsecond, nanosecond); - } -} - -const instance = MyTime.from("12:34:56.987654321"); -assert.sameValue(called, 1); - -MyTime.prototype.constructor = { - [Symbol.species]: undefined, -}; - -const calendar = Temporal.Calendar.from("iso8601"); -const result = instance.withCalendar(calendar); -assert.sameValue(result.hour, 12, "hour result"); -assert.sameValue(result.minute, 34, "minute result"); -assert.sameValue(result.second, 56, "second result"); -assert.sameValue(result.millisecond, 987, "millisecond result"); -assert.sameValue(result.microsecond, 654, "microsecond result"); -assert.sameValue(result.nanosecond, 321, "nanosecond result"); -assert.sameValue(result.calendar, calendar, "calendar result"); -assert.sameValue(called, 1); -assert.sameValue(Object.getPrototypeOf(result), Temporal.PlainTime.prototype); diff --git a/polyfill/test/PlainTime/prototype/withCalendar/subclass.js b/polyfill/test/PlainTime/prototype/withCalendar/subclass.js deleted file mode 100644 index 64074cd505..0000000000 --- a/polyfill/test/PlainTime/prototype/withCalendar/subclass.js +++ /dev/null @@ -1,35 +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.withcalendar -includes: [compareArray.js] ----*/ - -let called = 0; -const calendar = Temporal.Calendar.from("iso8601"); - -class MyTime extends Temporal.PlainTime { - constructor(hour, minute, second, millisecond, microsecond, nanosecond, calendarArg) { - assert.compareArray([hour, minute, second, millisecond, microsecond, nanosecond], [12, 34, 56, 987, 654, 321], "constructor arguments"); - if (called === 1) { - assert.sameValue(calendarArg, calendar, "calendar argument"); - } - ++called; - super(hour, minute, second, millisecond, microsecond, nanosecond, calendarArg); - } -} - -const instance = MyTime.from("12:34:56.987654321"); -assert.sameValue(called, 1); - -const result = instance.withCalendar(calendar); -assert.sameValue(result.hour, 12, "hour result"); -assert.sameValue(result.minute, 34, "minute result"); -assert.sameValue(result.second, 56, "second result"); -assert.sameValue(result.millisecond, 987, "millisecond result"); -assert.sameValue(result.microsecond, 654, "microsecond result"); -assert.sameValue(result.nanosecond, 321, "nanosecond result"); -assert.sameValue(result.calendar, calendar, "calendar result"); -assert.sameValue(called, 2); -assert.sameValue(Object.getPrototypeOf(result), MyTime.prototype); diff --git a/polyfill/test/now.mjs b/polyfill/test/now.mjs index 5be5d93652..9e640c1e23 100644 --- a/polyfill/test/now.mjs +++ b/polyfill/test/now.mjs @@ -19,13 +19,12 @@ import * as Temporal from 'proposal-temporal'; describe('Temporal.now', () => { describe('Structure', () => { it('Temporal.now is an object', () => equal(typeof Temporal.now, 'object')); - it('Temporal.now has 10 properties', () => equal(Object.keys(Temporal.now).length, 10)); + it('Temporal.now has 9 properties', () => equal(Object.keys(Temporal.now).length, 9)); it('Temporal.now.instant is a function', () => equal(typeof Temporal.now.instant, 'function')); it('Temporal.now.plainDateTime is a function', () => equal(typeof Temporal.now.plainDateTime, 'function')); it('Temporal.now.plainDateTimeISO is a function', () => equal(typeof Temporal.now.plainDateTimeISO, 'function')); it('Temporal.now.plainDate is a function', () => equal(typeof Temporal.now.plainDate, 'function')); it('Temporal.now.plainDateISO is a function', () => equal(typeof Temporal.now.plainDateISO, 'function')); - it('Temporal.now.plainTime is a function', () => equal(typeof Temporal.now.plainTime, 'function')); it('Temporal.now.plainTimeISO is a function', () => equal(typeof Temporal.now.plainTimeISO, 'function')); it('Temporal.now.timeZone is a function', () => equal(typeof Temporal.now.timeZone, 'function')); it('Temporal.now.zonedDateTimeISO is a function', () => equal(typeof Temporal.now.zonedDateTimeISO, 'function')); @@ -110,14 +109,6 @@ describe('Temporal.now', () => { equal(t.calendar.id, 'iso8601'); }); }); - describe('Temporal.now.plainTime()', () => { - it('Temporal.now.plainTime() returns a Time', () => { - const t = Temporal.now.plainTime('gregory'); - assert(t instanceof Temporal.PlainTime); - equal(t.calendar.id, 'gregory'); - }); - it('requires a calendar', () => throws(() => Temporal.now.plainTime(), RangeError)); - }); }); import { normalize } from 'path'; diff --git a/polyfill/test/plaintime.mjs b/polyfill/test/plaintime.mjs index f1688dd80f..ef4689a3fb 100644 --- a/polyfill/test/plaintime.mjs +++ b/polyfill/test/plaintime.mjs @@ -97,22 +97,6 @@ describe('Time', () => { }); describe('Construction', () => { describe('complete', () => { - let time; - it('time can be constructed', () => { - time = new PlainTime(15, 23, 30, 123, 456, 789, Temporal.Calendar.from('gregory')); - assert(time); - equal(typeof time, 'object'); - }); - it('time.hour is 15', () => equal(time.hour, 15)); - it('time.minute is 23', () => equal(time.minute, 23)); - it('time.second is 30', () => equal(time.second, 30)); - it('time.millisecond is 123', () => equal(time.millisecond, 123)); - it('time.microsecond is 456', () => equal(time.microsecond, 456)); - it('time.nanosecond is 789', () => equal(time.nanosecond, 789)); - it('time.calendar.id is gregory', () => equal(time.calendar.id, 'gregory')); - it('`${time}` is 15:23:30.123456789', () => equal(`${time}`, '15:23:30.123456789[c=gregory]')); - }); - describe('missing calendar', () => { let time; it('time can be constructed', () => { time = new PlainTime(15, 23, 30, 123, 456, 789); @@ -1121,26 +1105,6 @@ describe('Time', () => { equal(t2.toString(), '15:23:30'); equal(t3.toString(), '15:23:30.1234'); }); - const t3g = new PlainTime(15, 23, 30, 123, 400, 0, 'gregory'); - it('shows only non-ISO calendar if calendarName = auto', () => { - equal(t3.toString({ calendarName: 'auto' }), '15:23:30.1234'); - equal(t3g.toString({ calendarName: 'auto' }), '15:23:30.1234[c=gregory]'); - }); - it('shows ISO calendar if calendarName = always', () => { - equal(t3.toString({ calendarName: 'always' }), '15:23:30.1234[c=iso8601]'); - }); - it('omits non-ISO calendar if calendarName = never', () => { - equal(t3g.toString({ calendarName: 'never' }), '15:23:30.1234'); - }); - it('default is calendar = auto', () => { - equal(t3.toString(), '15:23:30.1234'); - equal(t3g.toString(), '15:23:30.1234[c=gregory]'); - }); - it('throws on invalid calendar', () => { - ['ALWAYS', 'sometimes', false, 3, null].forEach((calendarName) => { - throws(() => t3.toString({ calendarName }), RangeError); - }); - }); it('truncates to minute', () => { [t1, t2, t3].forEach((t) => equal(t.toString({ smallestUnit: 'minute' }), '15:23')); }); @@ -1361,6 +1325,7 @@ describe('Time', () => { equal(fields.millisecond, 123); equal(fields.microsecond, 456); equal(fields.nanosecond, 789); + equal(fields.calendar.id, 'iso8601'); }); it('enumerable', () => { const fields2 = { ...fields }; @@ -1370,6 +1335,7 @@ describe('Time', () => { equal(fields2.millisecond, 123); equal(fields2.microsecond, 456); equal(fields2.nanosecond, 789); + equal(fields2.calendar.id, 'iso8601'); }); it('as input to from()', () => { const t2 = PlainTime.from(fields); @@ -1404,8 +1370,7 @@ describe('Time', () => { fields.isoSecond, fields.isoMillisecond, fields.isoMicrosecond, - fields.isoNanosecond, - fields.calendar + fields.isoNanosecond ); assert(t1.equals(t2)); }); diff --git a/polyfill/test/usercalendar.mjs b/polyfill/test/usercalendar.mjs index c1ffbfdac2..e1026e6dc6 100644 --- a/polyfill/test/usercalendar.mjs +++ b/polyfill/test/usercalendar.mjs @@ -204,61 +204,30 @@ describe('Userland calendar', () => { }); describe('Trivial protocol implementation', () => { // For the purposes of testing, a nonsensical calendar that has 10-month - // years, 10-day months, 864-hour days, 10-minute hours and 10-second - // minutes, and the year zero is at the Unix epoch. - function decimalToISO(year, month, day, hour = 0, minute = 0, second = 0, overflow = 'constrain') { + // years, 10-day months, and the year zero is at the Unix epoch. + function decimalToISO(year, month, day, overflow = 'constrain') { if (overflow === 'constrain') { if (month < 1) month = 1; if (month > 10) month = 10; if (day < 1) day = 1; if (day > 10) day = 10; - if (hour < 0) hour = 0; - if (hour > 863) hour = 863; - if (minute < 0) minute = 0; - if (minute > 9) minute = 9; - if (second < 0) second = 0; - if (second > 9) second = 9; } else if (overflow === 'reject') { - if ( - month < 1 || - month > 10 || - day < 1 || - day > 10 || - hour < 0 || - hour > 863 || - minute < 0 || - minute > 9 || - second < 0 || - second > 9 - ) { + if (month < 1 || month > 10 || day < 1 || day > 10) { throw new RangeError('invalid value'); } } const days = year * 100 + (month - 1) * 10 + (day - 1); - const seconds = hour * 100 + minute * 10 + second; - const date = new Temporal.PlainDate(1970, 1, 1, 'iso8601').add({ days }); - const time = new Temporal.PlainTime().add({ seconds }); - return date.toPlainDateTime(time); + return new Temporal.PlainDate(1970, 1, 1, 'iso8601').add({ days }); } - function isoToDecimal(datetime) { - const { - isoYear = 1970, - isoMonth = 1, - isoDay = 1, - isoHour = 0, - isoMinute = 0, - isoSecond = 0 - } = datetime.getISOFields(); - const isoDateTime = new Temporal.PlainDateTime(isoYear, isoMonth, isoDay, isoHour, isoMinute, isoSecond, 0, 0, 0); - let { seconds } = isoDateTime.since(new Temporal.PlainDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0), { - largestUnit: 'seconds' - }); - let days = Math.floor(seconds / 86400); - seconds %= 86400; + function isoToDecimal(date) { + let { isoYear, isoMonth, isoDay } = date.getISOFields(); + let isoDate = new Temporal.PlainDate(isoYear, isoMonth, isoDay); + let { days } = isoDate.since(new Temporal.PlainDate(1970, 1, 1), { + largestUnit: 'days' + }); let year = Math.floor(days / 100); days %= 100; - if (isoYear < 1970) year *= -1; - return { year, days, seconds }; + return { year, days }; } const obj = { get id() { @@ -272,19 +241,6 @@ describe('Userland calendar', () => { const isoDateTime = decimalToISO(fields.year, fields.month, fields.day, 0, 0, 0, overflow); return new constructor(isoDateTime.year, isoDateTime.month, isoDateTime.day, this); }, - timeFromFields(fields, options, constructor) { - const { overflow = 'constrain' } = options ? options : {}; - const isoDateTime = decimalToISO(0, 1, 1, fields.hour, fields.minute, fields.second, overflow); - return new constructor( - isoDateTime.hour, - isoDateTime.minute, - isoDateTime.second, - fields.millisecond, - fields.microsecond, - fields.nanosecond, - this - ); - }, yearMonthFromFields(fields, options, constructor) { const { overflow = 'constrain' } = options ? options : {}; const isoDate = decimalToISO(fields.year, fields.month, 1, 0, 0, 0, overflow); @@ -364,7 +320,7 @@ describe('Userland calendar', () => { const date2 = Temporal.PlainDate.from('2020-06-05T12:00'); assert(date2.withCalendar(obj).equals(date)); }); - it('Temporal.PlainDateTime.from()', () => equal(`${dt}`, '2020-06-05T00:20:00[c=decimal]')); + it('Temporal.PlainDateTime.from()', () => equal(`${dt}`, '2020-06-05T12:00:00[c=decimal]')); it('Temporal.PlainDateTime fields', () => { equal(dt.year, 184); equal(dt.month, 2); @@ -381,7 +337,7 @@ describe('Userland calendar', () => { equal(dt2.year, 0); }); it('datetime.withCalendar()', () => { - const dt2 = Temporal.PlainDateTime.from('2020-06-05T00:20'); + const dt2 = Temporal.PlainDateTime.from('2020-06-05T12:00'); assert(dt2.withCalendar(obj).equals(dt)); }); it('Temporal.PlainYearMonth.from()', () => equal(`${ym}`, '2020-05-28[c=decimal]')); @@ -458,7 +414,7 @@ describe('Userland calendar', () => { }); it('works for DateTime.from(props)', () => { const dt = Temporal.PlainDateTime.from({ year: 0, month: 1, day: 1, hour: 12, calendar: 'decimal' }); - equal(`${dt}`, '1970-01-01T00:20:00[c=decimal]'); + equal(`${dt}`, '1970-01-01T12:00:00[c=decimal]'); }); it('works for DateTime.withCalendar', () => { const dt = Temporal.PlainDateTime.from('1970-01-01T00:00'); diff --git a/spec/abstractops.html b/spec/abstractops.html index a4d1ef900c..972cddf038 100644 --- a/spec/abstractops.html +++ b/spec/abstractops.html @@ -463,20 +463,20 @@

ToRelativeTemporalObject ( _options_ )

1. Set _calendar_ to ? GetISO8601Calendar(). 1. Else, 1. Set _calendar_ to ? ToTemporalCalendar(_calendar_). - 1. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"hour"*, *"microsecond"*, *"millisecond"*, *"minute"*, *"month"*, *"nanosecond"*, *"second"*, *"year"* »). + 1. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"day"*, *"month"*, *"year"* »). 1. Let _fields_ be ? ToTemporalDateTimeFields(_value_, _fieldNames_). 1. Let _temporalDate_ be ? DateFromFields(_calendar_, _fields_, %Temporal.PlainDate%). - 1. Let _temporalTime_ be ? TimeFromFields(_calendar_, _fields_, %Temporal.PlainTime%). + 1. Let _timeResult_ be ? ToTemporalTimeRecord(_fields_). 1. Let _result_ be the new Record { [[Year]]: _temporalDate_.[[ISOYear]], [[Month]]: _temporalDate_.[[ISOMonth]], [[Day]]: _temporalDate_.[[ISODay]], - [[Hour]]: _temporalTime_.[[ISOHour]], - [[Minute]]: _temporalTime_.[[ISOMinute]], - [[Second]]: _temporalTime_.[[ISOSecond]], - [[Millisecond]]: _temporalTime_.[[ISOMillisecond]], - [[Microsecond]]: _temporalTime_.[[ISOMicrosecond]], - [[Nanosecond]]: _temporalTime_.[[ISONanosecond]] + [[Hour]]: _timeResult_.[[Hour]], + [[Minute]]: _timeResult_.[[Minute]], + [[Second]]: _timeResult_.[[Second]], + [[Millisecond]]: _timeResult_.[[Millisecond]], + [[Microsecond]]: _timeResult_.[[Microsecond]], + [[Nanosecond]]: _timeResult_.[[Nanosecond]] }. 1. Let _offset_ be ? Get(_value_, *"offset"*). 1. Let _timeZone_ be ? Get(_value_, *"timeZone"*). diff --git a/spec/calendar.html b/spec/calendar.html index 9ec597bc29..100829217b 100644 --- a/spec/calendar.html +++ b/spec/calendar.html @@ -143,24 +143,6 @@

MonthDayFromFields ( _calendar_, _fields_, _constructor_ [ , _overflow_ ] )< - -

TimeFromFields ( _calendar_, _fields_, _constructor_ [ , _overflow_ ] )

- - 1. Assert: Type(_calendar_) is Object. - 1. Assert: Type(_fields_) is Object. - 1. If _overflow_ is *undefined*, then - 1. Set _overflow_ to *"constrain"*. - 1. Else, - 1. Assert: _overflow_ is either *"constrain"* or *"reject"*. - 1. Let _options_ be ! ObjectCreate(%Object.prototype%). - 1. Perform ! CreateDataPropertyOrThrow(_options_, *"overflow"*, _overflow_). - 1. Let _timeFromFields_ be ? Get(_calendar_, *"timeFromFields"*). - 1. Let _time_ be ? Call(_timeFromFields_, _calendar_, « _fields_, _options_, _constructor_ »). - 1. Perform ? RequireInternalSlot(_time_, [[InitializedTemporalTime]]). - 1. Return _time_. - -
-

FormatCalendarAnnotation ( _calendar_, _showCalendar_ )

diff --git a/spec/plaindate.html b/spec/plaindate.html index c9ee6d5666..7883b0598d 100644 --- a/spec/plaindate.html +++ b/spec/plaindate.html @@ -561,11 +561,9 @@

Temporal.PlainDate.prototype.toZonedDateTime ( _item_ )

1. Let _timeZone_ be ? ToTemporalTimeZone(_item_). 1. Let _temporalTime_ be *undefined*. 1. If _temporalTime_ is *undefined*, then - 1. TODO: use start of day in _calendar_. 1. Let _temporalDateTime_ be ? CreateTemporalDateTime(_temporalDate_.[[ISOYear]], _temporalDate_.[[ISOMonth]], _temporalDate_.[[ISODay]], 0, 0, 0, 0, 0, 0, _temporalDate_.[[Calendar]]). 1. Else, 1. Set _temporalTime_ to ? ToTemporalTime(_temporalTime_). - 1. TODO: verify calendars match. 1. Let _temporalDateTime_ be ? CreateTemporalDateTime(_temporalDate_.[[ISOYear]], _temporalDate_.[[ISOMonth]], _temporalDate_.[[ISODay]], _temporalTime_.[[Hour]], _temporalTime_.[[Minute]], _temporalTime_.[[Second]], _temporalTime_.[[Millisecond]], _temporalTime_.[[Microsecond]], _temporalTime_.[[Nanosecond]], _temporalDate_.[[Calendar]]). 1. Let _instant_ be ? GetTemporalInstantFor(_timeZone_, _temporalDateTime_, *"compatible"*). 1. Return ? CreateTemporalZonedDateTime(_instant_.[[Nanoseconds]], _timeZone_, _temporalDate_.[[Calendar]]). diff --git a/spec/plaindatetime.html b/spec/plaindatetime.html index b9bf0e4aff..d8ebaff218 100644 --- a/spec/plaindatetime.html +++ b/spec/plaindatetime.html @@ -425,10 +425,7 @@

Temporal.PlainDateTime.prototype.withPlainTime ( _plainTimeLike_ )

1. If _plainTimeLike_ is *undefined*, then 1. Return ? CreateTemporalDateTimeFromInstance(_temporalDateTime_, _temporalDateTime_.[[ISOYear]], _temporalDateTime_.[[ISOMonth]], _temporalDateTime_.[[ISODay]], 0, 0, 0, 0, 0, 0, _temporalDateTime_.[[Calendar]]). 1. Let _plainTime_ be ? ToTemporalTime(_plainTimeLike_). - 1. Let _dateCalendar_ be _temporalDateTime_.[[Calendar]]. - 1. Let _timeCalendar_ be _plainTime_.[[Calendar]]. - 1. Let _calendar_ be ? ConsolidateCalendars(_dateCalendar_, _timeCalendar_). - 1. Return ? CreateTemporalDateTimeFromInstance(_temporalDateTime_, _temporalDateTime_.[[ISOYear]], _temporalDateTime_.[[ISOMonth]], _temporalDateTime_.[[ISODay]], _plainTime_.[[ISOHour]], _plainTime_.[[ISOMinute]], _plainTime_.[[ISOSecond]], _plainTime_.[[ISOMillisecond]], _plainTime_.[[ISOMicrosecond]], _plainTime_.[[ISONanosecond]], _calendar_). + 1. Return ? CreateTemporalDateTimeFromInstance(_temporalDateTime_, _temporalDateTime_.[[ISOYear]], _temporalDateTime_.[[ISOMonth]], _temporalDateTime_.[[ISODay]], _plainTime_.[[ISOHour]], _plainTime_.[[ISOMinute]], _plainTime_.[[ISOSecond]], _plainTime_.[[ISOMillisecond]], _plainTime_.[[ISOMicrosecond]], _plainTime_.[[ISONanosecond]], _temporalDateTime_.[[Calendar]]).
@@ -442,9 +439,7 @@

Temporal.PlainDateTime.prototype.withPlainDate ( _plainDateLike_ )

1. Let _temporalDateTime_ be the *this* value. 1. Perform ? RequireInternalSlot(_temporalDateTime_, [[InitializedTemporalDateTime]]). 1. Let _plainDate_ be ? ToTemporalDate(_plainDateLike_). - 1. Let _dateCalendar_ be _plainDate_.[[Calendar]]. - 1. Let _timeCalendar_ be _temporalDateTime_.[[Calendar]]. - 1. Let _calendar_ be ? ConsolidateCalendars(_dateCalendar_, _timeCalendar_). + 1. Let _calendar_ be ? ConsolidateCalendars(_temporalDateTime_.[[Calendar]], _plainDate_.[[Calendar]]). 1. Return ? CreateTemporalDateTimeFromInstance(_temporalDateTime_, _plainDate_.[[ISOYear]], _plainDate_.[[ISOMonth]], _plainDate_.[[ISODay]], _temporalDateTime_.[[ISOHour]], _temporalDateTime_.[[ISOMinute]], _temporalDateTime_.[[ISOSecond]], _temporalDateTime_.[[ISOMillisecond]], _temporalDateTime_.[[ISOMicrosecond]], _temporalDateTime_.[[ISONanosecond]], _calendar_). @@ -925,17 +920,18 @@

InterpretTemporalDateTimeFields ( _calendar_, _fields_, _overflow_ )

1. Let _temporalDate_ be ? DateFromFields(_calendar_, _fields_, %Temporal.PlainDate%, _overflow_). - 1. Let _temporalTime_ be ? TimeFromFields(_calendar_, _fields_, %Temporal.PlainTime%, _overflow_). + 1. Let _timeResult_ be ? ToTemporalTimeRecord(_fields_). + 1. Let _timeResult_ be ? RegulateTime(_timeResult_.[[Hour]], _timeResult_.[[Minute]], _timeResult_.[[Second]], _timeResult_.[[Millisecond]], _timeResult_.[[Microsecond]], _timeResult_.[[Nanosecond]], _overflow_). 1. Return the new Record { [[Year]]: _temporalDate_.[[ISOYear]], [[Month]]: _temporalDate_.[[ISOMonth]], [[Day]]: _temporalDate_.[[ISODay]], - [[Hour]]: _temporalTime_.[[ISOHour]], - [[Minute]]: _temporalTime_.[[ISOMinute]], - [[Second]]: _temporalTime_.[[ISOSecond]], - [[Millisecond]]: _temporalTime_.[[ISOMillisecond]], - [[Microsecond]]: _temporalTime_.[[ISOMicrosecond]], - [[Nanosecond]]: _temporalTime_.[[ISONanosecond]] + [[Hour]]: _timeResult_.[[Hour]], + [[Minute]]: _timeResult_.[[Minute]], + [[Second]]: _timeResult_.[[Second]], + [[Millisecond]]: _timeResult_.[[Millisecond]], + [[Microsecond]]: _timeResult_.[[Microsecond]], + [[Nanosecond]]: _timeResult_.[[Nanosecond]] }. @@ -1190,7 +1186,6 @@

AddDateTime ( _year_, _month_, _day_, _hour_, _minute_, _second_, _milliseco 1. Let _options_ be ! OrdinaryObjectCreate(%Object.prototype%). 1. Perform ! CreateDataPropertyOrThrow(_options_, *"overflow"*, _overflow_). - 1. TODO: use `calendar.timeAdd()`. 1. Let _timeResult_ be ? AddTime(_hour_, _minute_, _second_, _millisecond_, _microsecond_, _nanosecond_, _hours_, _minutes_, _seconds_, _milliseconds_, _microseconds_, _nanoseconds_). 1. Let _datePart_ be ? CreateTemporalDate(_year_, _month_, _day_, _calendar_). 1. Let _dateDuration_ be ? CreateTemporalDuration(_years_, _months_, _weeks_, _days_ + _timeResult_.[[Days]]). @@ -1240,10 +1235,7 @@

DifferenceDateTime ( _y1_, _mon1_, _d1_, _h1_, _min1_, _s1_, _ms1_, _mus1_, The _largestUnit_ argument is used in _calendar_'s `dateUntil` method.

- 1. Let _time1_ be ? CreateTemporalTime(_h1_, _min1_, _s1_, _ms1_, _mus1_, _ns1_, _calendar_). - 1. Let _time2_ be ? CreateTemporalTime(_h2_, _min2_, _s2_, _ms2_, _mus2_, _ns2_, _calendar_). - 1. Let _timeUntil_ be ? Get(_calendar_, *"timeUntil"*). - 1. Let _timeDifference_ be ? Call(_timeUntil_, _calendar_, « _time1_, _time2_ »). + 1. Let _timeDifference_ be ? DifferenceTime(_h1_, _min1_, _s1_, _ms1_, _mus1_, _ns1_, _h2_, _min2_, _s2_, _ms2_, _mus2_, _ns2_). 1. Let _balanceResult_ be ? BalanceDate(_y1_, _mon1_, _d1_ + _timeDifference_.[[Days]]). 1. Let _date1_ be ? CreateTemporalDate(_balanceResult_.[[Year]], _balanceResult_.[[Month]], _balanceResult_.[[Day]]). 1. Let _date2_ be ? CreateTemporalDate(_y2_, _mon2_, _d2_). diff --git a/spec/plaintime.html b/spec/plaintime.html index a48e04734c..a9065d599b 100644 --- a/spec/plaintime.html +++ b/spec/plaintime.html @@ -128,7 +128,7 @@

get Temporal.Time.prototype.calendar

1. Let _temporalTime_ be the *this* value. 1. Perform ? RequireInternalSlot(_temporalTime_, [[InitializedTemporalTime]]). - 1. Return _temporalTime_.[[Calendar]]. + 1. Return ? GetISO8601Calendar(). @@ -222,8 +222,9 @@

Temporal.PlainTime.prototype.add ( _temporalDurationLike_ [ , _options_ ] )< 1. Let _duration_ be ? ToLimitedTemporalDuration(_temporalDurationLike_, « »). 1. Perform ? RejectDurationSign(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]]). 1. Set _options_ to ? NormalizeOptionsObject(_options_). - 1. Perform ? ToTemporalOverflow(_options_). + 1. Let _overflow_ be ? ToTemporalOverflow(_options_). 1. Let _result_ be ? AddTime(_temporalTime_.[[Hour]], _temporalTime_.[[Minute]], _temporalTime_.[[Second]], _temporalTime_.[[Millisecond]], _temporalTime_.[[Microsecond]], _temporalTime_.[[Nanosecond]], _duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]]). + 1. Set _result_ to ? RegulateTime(_result_.[[Hour]], _result_.[[Minute]], _result_.[[Second]], _result_.[[Millisecond]], _result_.[[Microsecond]], _result_.[[Nanosecond]], _overflow_). 1. Return ? CreateTemporalTimeFromInstance(_temporalTime_, _result_.[[Hour]], _result_.[[Minute]], _result_.[[Second]], _result_.[[Millisecond]], _result_.[[Microsecond]], _result_.[[Nanosecond]]). @@ -240,9 +241,10 @@

Temporal.PlainTime.prototype.subtract ( _temporalDurationLike_ [ , _options_ 1. Let _duration_ be ? ToLimitedTemporalDuration(_temporalDurationLike_, « »). 1. Perform ? RejectDurationSign(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]]). 1. Set _options_ to ? NormalizeOptionsObject(_options_). - 1. Perform ? ToTemporalOverflow(_options_). + 1. Let _overflow_ be ? ToTemporalOverflow(_options_). 1. Let _sign_ be ! DurationSign(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]]). 1. Let _result_ be ? AddTime(_temporalTime_.[[Hour]], _temporalTime_.[[Minute]], _temporalTime_.[[Second]], _temporalTime_.[[Millisecond]], _temporalTime_.[[Microsecond]], _temporalTime_.[[Nanosecond]], −_duration_.[[Hours]], −_duration_.[[Minutes]], −_duration_.[[Seconds]], −_duration_.[[Milliseconds]], −_duration_.[[Microseconds]], −_duration_.[[Nanoseconds]]). + 1. Set _result_ to ? RegulateTime(_result_.[[Hour]], _result_.[[Minute]], _result_.[[Second]], _result_.[[Millisecond]], _result_.[[Microsecond]], _result_.[[Nanosecond]], _overflow_). 1. Return ? CreateTemporalTimeFromInstance(_temporalTime_, _result_.[[Hour]], _result_.[[Minute]], _result_.[[Second]], _result_.[[Millisecond]], _result_.[[Microsecond]], _result_.[[Nanosecond]]). @@ -265,27 +267,35 @@

Temporal.PlainTime.prototype.with ( _temporalTimeLike_ [ , _options_ ] )

TODO. - 1. Let _constructor_ be ? SpeciesConstructor(_temporalTime_, %Temporal.PlainTime%). - 1. Return ? TimeFromFields(_calendar_, _fields_, _constructor_, _overflow_). -
- - - -

Temporal.PlainTime.prototype.withCalendar ( _calendar_ )

-

- The `withCalendar` method takes one argument _calendar_. - The following steps are taken: -

- - 1. Let _temporalTime_ be the *this* value. - 1. Perform ? RequireInternalSlot(_temporalTime_, [[InitializedTemporalTime]]). - 1. Let _calendar_ be ? ToTemporalCalendar(_calendar_). - 1. Return ? CreateTemporalTimeFromInstance(_temporalTime_, _temporalTime_.[[ISOHour]], _temporalTime_.[[ISOMinute]], _temporalTime_.[[ISOSecond]], _temporalTime_.[[ISOMillisecond]], _temporalTime_.[[ISOMicrosecond]], _temporalTime_.[[ISONanosecond]], _calendar_). + 1. If _partialTime_.[[Hour]] is not *undefined*, then + 1. Let _hour_ be _partialTime_.[[Hour]]. + 1. Else, + 1. Let _hour_ be _temporalTime_.[[ISOHour]]. + 1. If _partialTime_.[[Minute]] is not *undefined*, then + 1. Let _minute_ be _partialTime_.[[Minute]]. + 1. Else, + 1. Let _minute_ be _temporalTime_.[[ISOMinute]]. + 1. If _partialTime_.[[Second]] is not *undefined*, then + 1. Let _second_ be _partialTime_.[[Second]]. + 1. Else, + 1. Let _second_ be _temporalTime_.[[ISOSecond]]. + 1. If _partialTime_.[[Millisecond]] is not *undefined*, then + 1. Let _millisecond_ be _partialTime_.[[Millisecond]]. + 1. Else, + 1. Let _millisecond_ be _temporalTime_.[[ISOMillisecond]]. + 1. If _partialTime_.[[Microsecond]] is not *undefined*, then + 1. Let _microsecond_ be _partialTime_.[[Microsecond]]. + 1. Else, + 1. Let _microsecond_ be _temporalTime_.[[ISOMicrosecond]]. + 1. If _partialTime_.[[Nanosecond]] is not *undefined*, then + 1. Let _nanosecond_ be _partialTime_.[[Nanosecond]]. + 1. Else, + 1. Let _nanosecond_ be _temporalTime_.[[ISONanosecond]]. + 1. Let _result_ be ? RegulateTime(_hour_, _minute_, _second_, _millisecond_, _microsecond_, _nanosecond_, _overflow_). + 1. Return ? CreateTemporalTimeFromInstance(_temporalTime_, _result_.[[Hour]], _result_.[[Minute]], _result_.[[Second]], _result_.[[Millisecond]], _result_.[[Microsecond]], _result_.[[Nanosecond]]).
@@ -418,7 +428,6 @@

Temporal.PlainTime.prototype.toZonedDateTime ( _item_ )

1. If _temporalTimeZoneLike_ is *undefined*, then 1. Throw a *TypeError* exception. 1. Let _timeZone_ be ? ToTemporalTimeZone(_temporalTimeZoneLike_). - 1. TODO: verify calendars match. 1. Let _temporalDateTime_ be ? CreateTemporalDateTime(_temporalDate_.[[ISOYear]], _temporalDate_.[[ISOMonth]], _temporalDate_.[[ISODay]], _temporalTime_.[[Hour]], _temporalTime_.[[Minute]], _temporalTime_.[[Second]], _temporalTime_.[[Millisecond]], _temporalTime_.[[Microsecond]], _temporalTime_.[[Nanosecond]], _temporalDate_.[[Calendar]]). 1. Let _instant_ be ? GetTemporalInstantFor(_timeZone_, _temporalDateTime_, *"compatible"*). 1. Return ? CreateTemporalZonedDateTime(_instant_.[[Nanoseconds]], _timeZone_, _temporalDate_.[[Calendar]]). @@ -432,10 +441,34 @@

Temporal.PlainTime.prototype.getFields ( )

1. Let _temporalTime_ be the *this* value. - 1. Let _calendar_ be _temporalTime_.[[Calendar]]. - 1. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"hour"*, *"microsecond"*, *"millisecond"*, *"minute"*, *"nanosecond"*, *"second"* »). - 1. Let _fields_ be ? ToTemporalTimeFields(_temporalTime_, _fieldNames_). + 1. Let _record_ be ? ToTemporalTimeRecord(_temporalTime_). + 1. Let _fields_ be ! OrdinaryObjectCreate(%Object.prototype%). + 1. Let _calendar_ be ? GetISO8601Calendar(). 1. Perform ! CreateDataPropertyOrThrow(_fields_, *"calendar"*, _calendar_). + 1. For each row of , except the header row, in table order, do + 1. Let _p_ be the Property value of the current row. + 1. Let _v_ be the value of _record_'s internal slot whose name is the Internal Slot value of the current row. + 1. Perform ! CreateDataPropertyOrThrow(_fields_, _p_, _v_). + 1. Return _fields_. + + + + +

Temporal.PlainTime.prototype.getISOFields ( )

+

+ The following steps are taken: +

+ + 1. Let _temporalTime_ be the *this* value. + 1. Let _fields_ be ! OrdinaryObjectCreate(%Object.prototype%). + 1. Let _calendar_ be ? GetISO8601Calendar(). + 1. Perform ! CreateDataPropertyOrThrow(_fields_, *"calendar"*, _calendar_). + 1. Perform ! CreateDataPropertyOrThrow(_fields_, *"isoHour"*, 𝔽(_temporalTime_.[[ISOHour]])). + 1. Perform ! CreateDataPropertyOrThrow(_fields_, *"isoMicrosecond"*, 𝔽(_temporalTime_.[[ISOMicrosecond]])). + 1. Perform ! CreateDataPropertyOrThrow(_fields_, *"isoMillisecond"*, 𝔽(_temporalTime_.[[ISOMillisecond]])). + 1. Perform ! CreateDataPropertyOrThrow(_fields_, *"isoMinute"*, 𝔽(_temporalTime_.[[ISOMinute]])). + 1. Perform ! CreateDataPropertyOrThrow(_fields_, *"isoNanosecond"*, 𝔽(_temporalTime_.[[ISONanosecond]])). + 1. Perform ! CreateDataPropertyOrThrow(_fields_, *"isoSecond"*, 𝔽(_temporalTime_.[[ISOSecond]])). 1. Return _fields_.
@@ -452,9 +485,8 @@

Temporal.PlainTime.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 _roundResult_ be ? RoundTime(_temporalTime_.[[Hour]], _temporalTime_.[[Minute]], _temporalTime_.[[Second]], _temporalTime_.[[Millisecond]], _temporalTime_.[[Microsecond]], _temporalTime_.[[Nanosecond]], _precision_.[[Increment]], _precision_.[[Unit]], _roundingMode_). - 1. Return ? TemporalTimeToString(_roundResult_.[[Hour]], _roundResult_.[[Minute]], _roundResult_.[[Second]], _roundResult_.[[Millisecond]], _roundResult_.[[Microsecond]], _roundResult_.[[Nanosecond]], _temporalTime_.[[Calendar]], _precision_.[[Precision]], _showCalendar_). + 1. Return ? TemporalTimeToString(_roundResult_.[[Hour]], _roundResult_.[[Minute]], _roundResult_.[[Second]], _roundResult_.[[Millisecond]], _roundResult_.[[Microsecond]], _roundResult_.[[Nanosecond]], _temporalTime_.[[Calendar]], _precision_.[[Precision]]).
@@ -614,13 +646,16 @@

ToTemporalTime ( _item_ [ , _constructor_ [ , _overflow_ ] ] )

1. If _item_ has an [[InitializedTemporalTime]] internal slot, then 1. Return _item_. 1. Let _calendar_ be ? Get(_item_, *"calendar"*). - 1. If _calendar_ is *undefined*, set _calendar_ to ? GetISO8601Calendar(). - 1. Set _calendar_ to ? ToTemporalCalendar(_calendar_). - 1. Let _fieldNames_ be ? CalendarFields(_calendar_, « *"hour"*, *"microsecond"*, *"millisecond"*, *"minute"*, *"nanosecond"*, *"second"* »). - 1. Let _fields_ be ? ToTemporalTimeFields(_item_, _fieldNames_). - 1. Return ? TimeFromFields(_calendar_, _fields_, _constructor_, _overflow_). - 1. Let _string_ be ? ToString(_item_). - 1. Let _result_ be ? ParseTemporalTimeString(_string_). + 1. If _calendar_ is not *undefined*, then + 1. Set _calendar_ to ? ToTemporalCalendar(_calendar_). + 1. If ? CalendarToString(_calendar_) is not *"iso8601"*, then + 1. Throw a *RangeError* exception. + 1. Let _result_ be ? ToTemporalTimeRecord(_item_). + 1. Else, + 1. Let _string_ be ? ToString(_item_). + 1. Let _result_ be ? ParseTemporalTimeString(_string_). + 1. If _result_.[[Calendar]] is not one of *undefined* or *"iso8601"*, then + 1. Throw a *RangeError* exception. 1. Set _result_ to ? RegulateTime(_result_.[[Hour]], _result_.[[Minute]], _result_.[[Second]], _result_.[[Millisecond]], _result_.[[Microsecond]], _result_.[[Nanosecond]], _overflow_). 1. Return ? CreateTemporalTimeFromStatic(_constructor_, _result_.[[Hour]], _result_.[[Minute]], _result_.[[Second]], _result_.[[Millisecond]], _result_.[[Microsecond]], _result_.[[Nanosecond]]). @@ -829,28 +864,36 @@

CreateTemporalTimeFromStatic ( _constructor_, _hour_, _minute_, _second_, _m - -

ToTemporalTimeFields ( _temporalDateLike_, _fieldNames_ )

+ +

ToTemporalTimeRecord ( _temporalTimeLike_ )

1. Assert: Type(_temporalTimeLike_) is Object. - 1. Let _result_ be ? OrdinaryObjectCreate(%Object.prototype%). - 1. For each value _property_ of _fieldNames_, do - 1. Let _value_ be ? Get(_temporalDateLike_, _property_). - 1. If _property_ is one of *"hour"*, *"microsecond"*, *"millisecond"*, *"minute"*, *"nanosecond"*, or *"second"*, then - 1. Set _value_ to ? ToInteger(_value_). - 1. Perform ! CreateDataPropertyOrThrow(_result_, _property_, _value_). + 1. Let _result_ be the new Record { + [[Hour]]: *undefined*, + [[Minute]]: *undefined*, + [[Second]]: *undefined*, + [[Millisecond]]: *undefined*, + [[Microsecond]]: *undefined*, + [[Nanosecond]]: *undefined* + }. + 1. For each row of , except the header row, in table order, do + 1. Let _property_ be the Property value of the current row. + 1. Let _value_ be ? Get(_temporalTimeLike_, _property_). + 1. If _value_ is *undefined*, then + 1. Throw a *TypeError* exception. + 1. Set _value_ to ? ToInteger(_value_). + 1. Set _result_'s internal slot whose name is the Internal Slot value of the current row to _value_. 1. Return _result_.
-

TemporalTimeToString ( _hour_, _minute_, _second_, _millisecond_, _microsecond_, _nanosecond_, _calendar_, _precision_, _showCalendar_ )

+

TemporalTimeToString ( _hour_, _minute_, _second_, _millisecond_, _microsecond_, _nanosecond_, _calendar_, _precision_ )

1. Let _hour_ be _hour_ formatted as a two-digit decimal number, padded to the left with a zero if necessary. 1. Let _hour_ 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 _calendarString_ be ? FormatCalendarAnnotation(_calendar_, _showCalendar_). - 1. Return the string-concatenation of _hour_, the code unit 0x003A (COLON), _minute_, _seconds_, and _calendarString_. + 1. Return the string-concatenation of _hour_, the code unit 0x003A (COLON), _minute_, and _seconds_.
diff --git a/spec/zoneddatetime.html b/spec/zoneddatetime.html index eb146e1f68..c5ac4def55 100644 --- a/spec/zoneddatetime.html +++ b/spec/zoneddatetime.html @@ -616,9 +616,7 @@

Temporal.ZonedDateTime.prototype.withPlainTime ( _plainTimeLike_ )

1. Let _timeZone_ be _zonedDateTime_.[[TimeZone]]. 1. Let _instant_ be ? CreateTemporalInstant(_zonedDateTime_.[[Nanoseconds]]). 1. Let _plainDateTime_ be ? GetTemporalDateTimeFor(_timeZone_, _instant_). - 1. Let _dateCalendar_ be _plainDateTime_.[[Calendar]]. - 1. Let _timeCalendar_ be _plainTime_.[[Calendar]]. - 1. Let _calendar_ be ? ConsolidateCalendars(_dateCalendar_, _timeCalendar_). + 1. Let _calendar_ be _zonedDateTime_.[[Calendar]]. 1. Let _resultPlainDateTime_ be ? CreateTemporalDateTime(_plainDateTime_.[[ISOYear]], _plainDateTime_.[[ISOMonth]], _plainDateTime_.[[ISODay]], _plainTime_.[[ISOHour]], _plainTime_.[[ISOMinute]], _plainTime_.[[ISOSecond]], _plainTime_.[[ISOMillisecond]], _plainTime_.[[ISOMicrosecond]], _plainTime_.[[ISONanosecond]], _calendar_). 1. Let _instant_ be ? GetTemporalInstantFor(_timeZone_, _resultPlainDateTime_, *"compatible"*). 1. Return ? CreateTemporalZonedDateTimeFromInstance(_zonedDateTime_, _instant_.[[Nanoseconds]], _timeZone_, _calendar_). @@ -638,9 +636,7 @@

Temporal.ZonedDateTime.prototype.withPlainDate ( _plainDateLike_ )

1. Let _timeZone_ be _zonedDateTime_.[[TimeZone]]. 1. Let _instant_ be ? CreateTemporalInstant(_zonedDateTime_.[[Nanoseconds]]). 1. Let _plainDateTime_ be ? GetTemporalDateTimeFor(_timeZone_, _instant_). - 1. Let _dateCalendar_ be _plainDate_.[[Calendar]]. - 1. Let _timeCalendar_ be _plainDateTime_.[[Calendar]]. - 1. Let _calendar_ be ? ConsolidateCalendars(_dateCalendar_, _timeCalendar_). + 1. Let _calendar_ be ? ConsolidateCalendars(_zonedDateTime_.[[Calendar]], _plainDate_.[[Calendar]]). 1. Let _resultPlainDateTime_ be ? CreateTemporalDateTime(_plainDate_.[[ISOYear]], _plainDate_.[[ISOMonth]], _plainDate_.[[ISODay]], _plainDateTime_.[[ISOHour]], _plainDateTime_.[[ISOMinute]], _plainDateTime_.[[ISOSecond]], _plainDateTime_.[[ISOMillisecond]], _plainDateTime_.[[ISOMicrosecond]], _plainDateTime_.[[ISONanosecond]], _calendar_). 1. Let _instant_ be ? GetTemporalInstantFor(_timeZone_, _resultPlainDateTime_, *"compatible"*). 1. Return ? CreateTemporalZonedDateTimeFromInstance(_zonedDateTime_, _instant_.[[Nanoseconds]], _timeZone_, _calendar_).