Skip to content

Commit

Permalink
Normative: Remove PlainTime.toPlainDateTime/toZonedDateTime methods
Browse files Browse the repository at this point in the history
  • Loading branch information
ptomato committed May 24, 2024
1 parent ee9f3f8 commit 69c9152
Show file tree
Hide file tree
Showing 4 changed files with 1 addition and 199 deletions.
16 changes: 1 addition & 15 deletions docs/cookbook/makeExpandedTemporal.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -156,31 +156,17 @@ class ExpandedPlainDateTime extends Temporal.PlainDateTime {
}
}

class ExpandedPlainTime extends Temporal.PlainTime {
toPlainDateTime(date) {
return ExpandedPlainDateTime._convert(super.toPlainDateTime(date), date.year);
}

static from(item) {
const { hour, minute, second, millisecond, microsecond, nanosecond } = super.from(item);
return new ExpandedPlainTime(hour, minute, second, millisecond, microsecond, nanosecond);
}
}

function makeExpandedTemporal() {
return {
...Temporal,
PlainDate: ExpandedPlainDate,
PlainDateTime: ExpandedPlainDateTime,
PlainTime: ExpandedPlainTime
PlainDateTime: ExpandedPlainDateTime
};
}

const ExpandedTemporal = makeExpandedTemporal();

const date = ExpandedTemporal.PlainDate.from({ year: 635427810, month: 2, day: 2 });
assert.equal(date.toString(), '+0635427810-02-02');
const dateTime = ExpandedTemporal.PlainTime.from('10:23').toPlainDateTime(date);
assert.equal(dateTime.toString(), '+0635427810-02-02T10:23:00');
const dateFromString = ExpandedTemporal.PlainDateTime.from('-0075529144-02-29T12:53:27.55');
assert.equal(dateFromString.year, -75529144n);
62 changes: 0 additions & 62 deletions docs/plaintime.md
Original file line number Diff line number Diff line change
Expand Up @@ -518,68 +518,6 @@ This method overrides `Object.prototype.valueOf()` and always throws an exceptio
This is because it's not possible to compare `Temporal.PlainTime` objects with the relational operators `<`, `<=`, `>`, or `>=`.
Use `Temporal.PlainTime.compare()` for this, or `time.equals()` for equality.

### time.**toZonedDateTime**(_item_: object) : Temporal.ZonedDateTime

**Parameters:**

- `item` (object): an object with properties to be added to `time`. The following properties are recognized:
- `plainDate` (required `Temporal.PlainDate` or value convertible to one): a date used to merge into a `Temporal.ZonedDateTime` along with `time`.
- `timeZone` (required `Temporal.TimeZone` or value convertible to one, or an object implementing the [time zone protocol](./timezone.md#custom-time-zones)): the time zone in which to interpret `time` and `plainDate`.

**Returns:** a `Temporal.ZonedDateTime` object that represents the clock `time` on the calendar `plainDate` projected into `timeZone`.

This method can be used to convert `Temporal.PlainTime` into a `Temporal.ZonedDateTime`, by supplying the time zone and date.

For a list of IANA time zone names, see the current version of the [IANA time zone database](https://www.iana.org/time-zones).
A convenient list is also available [on Wikipedia](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones), although it might not reflect the latest official status.

In addition to the `timeZone`, the converted object carries a copy of all the relevant fields of `time` and `plainDate`.
If `plainDate` is not a `Temporal.PlainDate` object, then it will be converted to one as if it were passed to `Temporal.PlainDate.from()`.
This method produces identical results to [`Temporal.PlainDate.from(plainDate).toPlainDateTime(time).toZonedDateTime(timeZone)`](./plaindate.md#toZonedDateTime).

In the case of ambiguity caused by DST or other time zone changes, the earlier time will be used for backward transitions and the later time for forward transitions.
When interoperating with existing code or services, this matches the behavior of legacy `Date` as well as libraries like moment.js, Luxon, and date-fns.
This mode also matches the behavior of cross-platform standards like [RFC 5545 (iCalendar)](https://tools.ietf.org/html/rfc5545).

During "skipped" clock time like the hour after DST starts in the Spring, this method interprets invalid times using the pre-transition time zone offset.
This behavior avoids exceptions when converting nonexistent date/time values to `Temporal.ZonedDateTime`, but it also means that values during these periods will result in a different `Temporal.PlainTime` value in "round-trip" conversions to `Temporal.ZonedDateTime` and back again.

For usage examples and a more complete explanation of how this disambiguation works, see [Resolving ambiguity](./ambiguity.md).

If the result is outside the range that `Temporal.ZonedDateTime` can represent (approximately half a million years centered on the [Unix epoch](https://en.wikipedia.org/wiki/Unix_time)), then a `RangeError` will be thrown.

Usage example:

```javascript
plainTime = Temporal.PlainTime.from('15:23:30.003');
plainDate = Temporal.PlainDate.from('2006-08-24');
plainTime.toZonedDateTime({ timeZone: 'America/Los_Angeles', plainDate });
// => 2006-08-24T15:23:30.003-07:00[America/Los_Angeles]
```

### time.**toPlainDateTime**(_date_: Temporal.PlainDate | object | string) : Temporal.PlainDateTime

**Parameters:**

- `date` (`Temporal.PlainDate` or value convertible to one): A calendar date on which to place `time`.

**Returns:** a `Temporal.PlainDateTime` object that represents the wall-clock time `time` on the calendar date `date`.

This method can be used to convert `Temporal.PlainTime` into a `Temporal.PlainDateTime`, by supplying the calendar date to use.
The converted object carries a copy of all the relevant fields of `date` and `time`.

This has identical results to [`Temporal.PlainDate.from(date).toPlainDateTime(time)`](./plaindate.md#toPlainDateTime).

If `date` is not a `Temporal.PlainDate` object, then it will be converted to one as if it were passed to `Temporal.PlainDate.from()`.

Usage example:

```javascript
time = Temporal.PlainTime.from('15:23:30.003');
date = Temporal.PlainDate.from('2006-08-24');
time.toPlainDateTime(date); // => 2006-08-24T15:23:30.003
```

### time.**getISOFields**(): { isoHour: number, isoMinute: number, isoSecond: number, isoMillisecond: number, isoMicrosecond: number, isoNanosecond: number }

**Returns:** a plain object with properties expressing `time` in the ISO 8601 calendar.
Expand Down
81 changes: 0 additions & 81 deletions polyfill/lib/plaintime.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,14 @@
import * as ES from './ecmascript.mjs';
import { DateTimeFormat } from './intl.mjs';
import { MakeIntrinsicClass } from './intrinsicclass.mjs';
import { TimeZoneMethodRecord } from './methodrecord.mjs';

import {
ISO_YEAR,
ISO_MONTH,
ISO_DAY,
ISO_HOUR,
ISO_MINUTE,
ISO_SECOND,
ISO_MILLISECOND,
ISO_MICROSECOND,
ISO_NANOSECOND,
CALENDAR,
EPOCHNANOSECONDS,
CreateSlots,
GetSlot,
SetSlot
Expand Down Expand Up @@ -213,81 +207,6 @@ export class PlainTime {
ES.ValueOfThrows('PlainTime');
}

toPlainDateTime(temporalDate) {
if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver');

temporalDate = ES.ToTemporalDate(temporalDate);
const year = GetSlot(temporalDate, ISO_YEAR);
const month = GetSlot(temporalDate, ISO_MONTH);
const day = GetSlot(temporalDate, ISO_DAY);
const calendar = GetSlot(temporalDate, CALENDAR);

const hour = GetSlot(this, ISO_HOUR);
const minute = GetSlot(this, ISO_MINUTE);
const second = GetSlot(this, ISO_SECOND);
const millisecond = GetSlot(this, ISO_MILLISECOND);
const microsecond = GetSlot(this, ISO_MICROSECOND);
const nanosecond = GetSlot(this, ISO_NANOSECOND);

return ES.CreateTemporalDateTime(
year,
month,
day,
hour,
minute,
second,
millisecond,
microsecond,
nanosecond,
calendar
);
}
toZonedDateTime(item) {
if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver');

if (ES.Type(item) !== 'Object') {
throw new TypeError('invalid argument');
}

const dateLike = item.plainDate;
if (dateLike === undefined) {
throw new TypeError('missing date property');
}
const temporalDate = ES.ToTemporalDate(dateLike);

const timeZoneLike = item.timeZone;
if (timeZoneLike === undefined) {
throw new TypeError('missing timeZone property');
}
const timeZone = ES.ToTemporalTimeZoneSlotValue(timeZoneLike);

const year = GetSlot(temporalDate, ISO_YEAR);
const month = GetSlot(temporalDate, ISO_MONTH);
const day = GetSlot(temporalDate, ISO_DAY);
const calendar = GetSlot(temporalDate, CALENDAR);
const hour = GetSlot(this, ISO_HOUR);
const minute = GetSlot(this, ISO_MINUTE);
const second = GetSlot(this, ISO_SECOND);
const millisecond = GetSlot(this, ISO_MILLISECOND);
const microsecond = GetSlot(this, ISO_MICROSECOND);
const nanosecond = GetSlot(this, ISO_NANOSECOND);

const dt = ES.CreateTemporalDateTime(
year,
month,
day,
hour,
minute,
second,
millisecond,
microsecond,
nanosecond,
calendar
);
const timeZoneRec = new TimeZoneMethodRecord(timeZone, ['getOffsetNanosecondsFor', 'getPossibleInstantsFor']);
const instant = ES.GetInstantFor(timeZoneRec, dt, 'compatible');
return ES.CreateTemporalZonedDateTime(GetSlot(instant, EPOCHNANOSECONDS), timeZone, calendar);
}
getISOFields() {
if (!ES.IsTemporalTime(this)) throw new TypeError('invalid receiver');
return {
Expand Down
41 changes: 0 additions & 41 deletions spec/plaintime.html
Original file line number Diff line number Diff line change
Expand Up @@ -297,47 +297,6 @@ <h1>Temporal.PlainTime.prototype.equals ( _other_ )</h1>
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal.plaintime.prototype.toplaindatetime">
<h1>Temporal.PlainTime.prototype.toPlainDateTime ( _temporalDate_ )</h1>
<p>
This method performs the following steps when called:
</p>
<emu-alg>
1. Let _temporalTime_ be the *this* value.
1. Perform ? RequireInternalSlot(_temporalTime_, [[InitializedTemporalTime]]).
1. Set _temporalDate_ to ? ToTemporalDate(_temporalDate_).
1. Return ? CreateTemporalDateTime(_temporalDate_.[[ISOYear]], _temporalDate_.[[ISOMonth]], _temporalDate_.[[ISODay]],
_temporalTime_.[[ISOHour]], _temporalTime_.[[ISOMinute]], _temporalTime_.[[ISOSecond]],
_temporalTime_.[[ISOMillisecond]], _temporalTime_.[[ISOMicrosecond]], _temporalTime_.[[ISONanosecond]],
_temporalDate_.[[Calendar]]).
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal.plaintime.prototype.tozoneddatetime">
<h1>Temporal.PlainTime.prototype.toZonedDateTime ( _item_ )</h1>
<p>
This method performs the following steps when called:
</p>
<emu-alg>
1. Let _temporalTime_ be the *this* value.
1. Perform ? RequireInternalSlot(_temporalTime_, [[InitializedTemporalTime]]).
1. If _item_ is not an Object, then
1. Throw a *TypeError* exception.
1. Let _temporalDateLike_ be ? Get(_item_, *"plainDate"*).
1. If _temporalDateLike_ is *undefined*, then
1. Throw a *TypeError* exception.
1. Let _temporalDate_ be ? ToTemporalDate(_temporalDateLike_).
1. Let _temporalTimeZoneLike_ be ? Get(_item_, *"timeZone"*).
1. If _temporalTimeZoneLike_ is *undefined*, then
1. Throw a *TypeError* exception.
1. Let _timeZone_ be ? ToTemporalTimeZoneSlotValue(_temporalTimeZoneLike_).
1. Let _temporalDateTime_ be ? CreateTemporalDateTime(_temporalDate_.[[ISOYear]], _temporalDate_.[[ISOMonth]], _temporalDate_.[[ISODay]], _temporalTime_.[[ISOHour]], _temporalTime_.[[ISOMinute]], _temporalTime_.[[ISOSecond]], _temporalTime_.[[ISOMillisecond]], _temporalTime_.[[ISOMicrosecond]], _temporalTime_.[[ISONanosecond]], _temporalDate_.[[Calendar]]).
1. Let _timeZoneRec_ be ? CreateTimeZoneMethodsRecord(_timeZone_, « ~get-offset-nanoseconds-for~, ~get-possible-instants-for~ »).
1. Let _instant_ be ? GetInstantFor(_timeZoneRec_, _temporalDateTime_, *"compatible"*).
1. Return ! CreateTemporalZonedDateTime(_instant_.[[Nanoseconds]], _timeZone_, _temporalDate_.[[Calendar]]).
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal.plaintime.prototype.getisofields">
<h1>Temporal.PlainTime.prototype.getISOFields ( )</h1>
<p>
Expand Down

0 comments on commit 69c9152

Please sign in to comment.