Skip to content

Commit

Permalink
Normative: Remove withPlainDate() methods
Browse files Browse the repository at this point in the history
Closes: #2847
  • Loading branch information
ptomato committed Jun 13, 2024
1 parent 0b6d1c1 commit f7acbd2
Show file tree
Hide file tree
Showing 9 changed files with 0 additions and 230 deletions.
44 changes: 0 additions & 44 deletions docs/plaindatetime.md
Original file line number Diff line number Diff line change
Expand Up @@ -512,50 +512,6 @@ dt.withPlainTime('12:34'); // => 2015-12-07T12:34:00
dt.add({ days: 2, hours: 22 }).withPlainTime('00:00'); // => 2015-12-10T00:00:00
```

### datetime.**withPlainDate**(_plainDate_: object | string) : Temporal.PlainDateTime

**Parameters:**

- `plainDate` (`Temporal.PlainDate` or plain object or string): The calendar date that should replace the current calendar date of `datetime`.

**Returns:** a new `Temporal.PlainDateTime` object which is the date indicated by `datetime`, combined with the date represented by `plainDate`.

Valid input to `withPlainDate` is the same as valid input to `Temporal.PlainDate.from`, including strings like `2000-03-01`, plain object property bags like `{ year: 2020, month: 3, day: 1 }`, or `Temporal` objects that contain a `year`, `month`, and `day` property, including `Temporal.PlainDate`, `Temporal.PlainDateTime`, or `Temporal.ZonedDateTime`.

All three date units (`year`, `month`, and `day`) are required.
`Temporal.YearMonth` and `Temporal.MonthDay` are not valid input because they lack all date units.
Both of those types have a `toPlainDate` method that can be used to obtain a `Temporal.PlainDate` which can in turn be used as input to `withPlainDate`.

If `plainDate` contains a non-ISO 8601 calendar, then the result of `withPlainDate` will be the calendar of `plainDate`.
However, if `datetime.calendar` is already a non-ISO 8601 calendar, then this method will throw a `RangeError`.
To resolve the error, first convert one of the instances to the same calendar or the ISO 8601 calendar, e.g. using `.withCalendar('iso8601')`.

This method is similar to `with`, but with a few important differences:

- `withPlainDate` accepts strings, Temporal objects, or object property bags.
`with` only accepts object property bags and does not accept strings nor `Temporal.PlainDate` objects because they can contain calendar information.
- `withPlainDate` will update all date units, while `with` only changes individual units that are present in the input, e.g. setting the `day` to `1` while leaving `month` and `year` unchanged.

If `plainDate` is a `Temporal.PlainDate` object, then this method returns the same result as `plainDate.toPlainDateTime(datetime)` but can be easier to use, especially when chained to previous operations that return a `Temporal.PlainDateTime`.

Usage example:

```javascript
dt = Temporal.PlainDateTime.from('1995-12-07T03:24:30');
dt.withPlainDate({ year: 2000, month: 6, day: 1 }); // => 2000-06-01T03:24:30
date = Temporal.PlainDate.from('2020-01-23');
dt.withPlainDate(date); // => 2020-01-23T03:24:30
dt.withPlainDate('2018-09-15'); // => 2018-09-15T03:24:30

// easier for chaining
dt.add({ hours: 12 }).withPlainDate('2000-06-01'); // => 2000-06-01T15:24:30

// result contains a non-ISO calendar if present in the input
dt.withCalendar('japanese').withPlainDate('2008-09-06'); // => 2008-09-06T03:24:30[u-ca=japanese]
dt.withPlainDate('2017-09-06[u-ca=japanese]'); // => 2017-09-06T03:24:30[u-ca=japanese]
/* WRONG */ dt.withCalendar('japanese').withPlainDate('2017-09-06[u-ca=hebrew]'); // => RangeError (calendar conflict)
```

### datetime.**withCalendar**(_calendar_: object | string) : Temporal.PlainDateTime

**Parameters:**
Expand Down
46 changes: 0 additions & 46 deletions docs/zoneddatetime.md
Original file line number Diff line number Diff line change
Expand Up @@ -786,52 +786,6 @@ zdt.withPlainTime('12:34'); // => 2015-12-07T12:34:00-08:00[America/Los_Angeles]
zdt.add({ days: 2, hours: 22 }).withPlainTime('00:00'); // => 2015-12-10T00:00:00-08:00[America/Los_Angeles]
```

### zonedDateTime.**withPlainDate**(_plainDate_: object | string) : Temporal.ZonedDateTime

**Parameters:**

- `plainDate` (`Temporal.PlainDate` or plain object or string): The calendar date that should replace the current calendar date of `zonedDateTime`.

**Returns:** a new `Temporal.ZonedDateTime` object which replaces the calendar date of `zonedDateTime` with the calendar date represented by `plainDate`.

Valid input to `withPlainDate` is the same as valid input to `Temporal.PlainDate.from`, including strings like `2000-03-01`, plain object property bags like `{ year: 2020, month: 3, day: 1 }`, or `Temporal` objects that contain a `year`, `month`, and `day` property, including `Temporal.PlainDate`, `Temporal.ZonedDateTime`, or `Temporal.PlainDateTime`.

All three date units (`year`, `month`, and `day`) are required.
`Temporal.YearMonth` and `Temporal.MonthDay` are not valid input because they lack all date units.
Both of those types have a `toPlainDate` method that can be used to obtain a `Temporal.PlainDate` which can in turn be used as input to `withPlainDate`.

If `plainDate` contains a non-ISO 8601 calendar, then the result of `withPlainDate` will be the calendar of `plainDate`.
However, if `zonedDateTime.calendar` is already a non-ISO 8601 calendar, then this method will throw a `RangeError`.
To resolve the error, first convert one of the instances to the same calendar or the ISO 8601 calendar, e.g. using `.withCalendar('iso8601')`.

This method is similar to `with`, but with a few important differences:

- `withPlainDate` accepts strings, Temporal objects, or object property bags.
`with` only accepts object property bags and does not accept strings nor `Temporal.PlainDate` objects because they can contain calendar information.
- `withPlainDate` will update all date units, while `with` only changes individual units that are present in the input, e.g. setting the `day` to `1` while leaving `month` and `year` unchanged.
- `withPlainDate` does not accept options like `disambiguation` or `offset`.
For fine-grained control, use `with`.

If `plainDate` is a `Temporal.PlainDate` object, then this method returns the same result as `plainDate.toZonedDateTime({ plainDate: zonedDateTime, timeZone: zonedDateTime})` but can be easier to use, especially when chained to previous operations that return a `Temporal.ZonedDateTime`.

Usage example:

```javascript
zdt = Temporal.ZonedDateTime.from('1995-12-07T03:24:30-08:00[America/Los_Angeles]');
zdt.withPlainDate({ year: 2000, month: 6, day: 1 }); // => 2000-06-01T03:24:30-07:00[America/Los_Angeles]
date = Temporal.PlainDate.from('2020-01-23');
zdt.withPlainDate(date); // => 2020-01-23T03:24:30-08:00[America/Los_Angeles]
zdt.withPlainDate('2018-09-15'); // => 2018-09-15T03:24:30-07:00[America/Los_Angeles]

// easier for chaining
zdt.add({ hours: 12 }).withPlainDate('2000-06-01'); // => 2000-06-01T15:24:30-07:00[America/Los_Angeles]

// result contains a non-ISO calendar if present in the input
zdt.withCalendar('japanese').withPlainDate('2008-09-06'); // => 2008-09-06T03:24:30-07:00[America/Los_Angeles][u-ca=japanese]
zdt.withPlainDate('2017-09-06[u-ca=japanese]'); // => 2017-09-06T03:24:30-07:00[America/Los_Angeles][u-ca=japanese]
/* WRONG */ zdt.withCalendar('japanese').withPlainDate('2017-09-06[u-ca=hebrew]'); // => RangeError (calendar conflict)
```

### zonedDateTime.**withTimeZone**(_timeZone_: object | string) : Temporal.ZonedDateTime

**Parameters:**
Expand Down
2 changes: 0 additions & 2 deletions polyfill/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -941,7 +941,6 @@ export namespace Temporal {
equals(other: Temporal.PlainDateTime | PlainDateTimeLike | string): boolean;
with(dateTimeLike: PlainDateTimeLike, options?: AssignmentOptions): Temporal.PlainDateTime;
withPlainTime(timeLike?: Temporal.PlainTime | PlainTimeLike | string): Temporal.PlainDateTime;
withPlainDate(dateLike: Temporal.PlainDate | PlainDateLike | string): Temporal.PlainDateTime;
withCalendar(calendar: CalendarLike): Temporal.PlainDateTime;
add(durationLike: Temporal.Duration | DurationLike | string, options?: ArithmeticOptions): Temporal.PlainDateTime;
subtract(
Expand Down Expand Up @@ -1292,7 +1291,6 @@ export namespace Temporal {
equals(other: Temporal.ZonedDateTime | ZonedDateTimeLike | string): boolean;
with(zonedDateTimeLike: ZonedDateTimeLike, options?: ZonedDateTimeAssignmentOptions): Temporal.ZonedDateTime;
withPlainTime(timeLike?: Temporal.PlainTime | PlainTimeLike | string): Temporal.ZonedDateTime;
withPlainDate(dateLike: Temporal.PlainDate | PlainDateLike | string): Temporal.ZonedDateTime;
withCalendar(calendar: CalendarLike): Temporal.ZonedDateTime;
withTimeZone(timeZone: TimeZoneLike): Temporal.ZonedDateTime;
add(durationLike: Temporal.Duration | DurationLike | string, options?: ArithmeticOptions): Temporal.ZonedDateTime;
Expand Down
13 changes: 0 additions & 13 deletions polyfill/lib/ecmascript.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2266,19 +2266,6 @@ export function ThrowIfCalendarsNotEqual(one, two, errorMessageAction) {
}
}

export function ConsolidateCalendars(one, two) {
if (one === two) return two;
const sOne = ToTemporalCalendarIdentifier(one);
const sTwo = ToTemporalCalendarIdentifier(two);
if (sOne === sTwo || sOne === 'iso8601') {
return two;
} else if (sTwo === 'iso8601') {
return one;
} else {
throw new RangeError('irreconcilable calendars');
}
}

export function CalendarDateFromFields(calendarRec, fields, options) {
const result = calendarRec.dateFromFields(fields, options);
if (!calendarRec.isBuiltIn() && !IsTemporalDate(result)) throw new TypeError('invalid result');
Expand Down
30 changes: 0 additions & 30 deletions polyfill/lib/plaindatetime.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -205,36 +205,6 @@ export class PlainDateTime {
GetSlot(this, CALENDAR)
);
}
withPlainDate(temporalDate) {
if (!ES.IsTemporalDateTime(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);
let 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);

calendar = ES.ConsolidateCalendars(GetSlot(this, CALENDAR), calendar);
return ES.CreateTemporalDateTime(
year,
month,
day,
hour,
minute,
second,
millisecond,
microsecond,
nanosecond,
calendar
);
}
withCalendar(calendar) {
if (!ES.IsTemporalDateTime(this)) throw new TypeError('invalid receiver');
calendar = ES.ToTemporalCalendarSlotValue(calendar);
Expand Down
37 changes: 0 additions & 37 deletions polyfill/lib/zoneddatetime.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -258,43 +258,6 @@ export class ZonedDateTime {

return ES.CreateTemporalZonedDateTime(epochNanoseconds, timeZoneRec.receiver, calendarRec.receiver);
}
withPlainDate(temporalDate) {
if (!ES.IsTemporalZonedDateTime(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);
let calendar = GetSlot(temporalDate, CALENDAR);
const timeZoneRec = new TimeZoneMethodRecord(GetSlot(this, TIME_ZONE), [
'getOffsetNanosecondsFor',
'getPossibleInstantsFor'
]);
const thisDt = ES.GetPlainDateTimeFor(timeZoneRec, GetSlot(this, INSTANT), GetSlot(this, CALENDAR));
const hour = GetSlot(thisDt, ISO_HOUR);
const minute = GetSlot(thisDt, ISO_MINUTE);
const second = GetSlot(thisDt, ISO_SECOND);
const millisecond = GetSlot(thisDt, ISO_MILLISECOND);
const microsecond = GetSlot(thisDt, ISO_MICROSECOND);
const nanosecond = GetSlot(thisDt, ISO_NANOSECOND);

calendar = ES.ConsolidateCalendars(GetSlot(this, CALENDAR), calendar);
const dt = ES.CreateTemporalDateTime(
year,
month,
day,
hour,
minute,
second,
millisecond,
microsecond,
nanosecond,
calendar
);
const instant = ES.GetInstantFor(timeZoneRec, dt, 'compatible');
return ES.CreateTemporalZonedDateTime(GetSlot(instant, EPOCHNANOSECONDS), timeZoneRec.receiver, calendar);
}
withPlainTime(temporalTime = undefined) {
if (!ES.IsTemporalZonedDateTime(this)) throw new TypeError('invalid receiver');

Expand Down
25 changes: 0 additions & 25 deletions spec/calendar.html
Original file line number Diff line number Diff line change
Expand Up @@ -1020,31 +1020,6 @@ <h1>
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal-consolidatecalendars" type="abstract operation">
<h1>
ConsolidateCalendars (
_one_: a String or Object,
_two_: a String or Object,
): either a normal completion containing either a String or Object, or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>
It returns the calendar that should take priority when combining two Temporal objects with different calendars, or throws an exception if the calendars cannot be combined.
Calendars can be combined when they have the same identifier or exactly one of them has identifier *"iso8601"*, and _calendarTwo_ takes priority in any combination unless it is the calendar with that identifier.
</dd>
</dl>
<emu-alg>
1. If _one_ and _two_ are the same Object value, return _two_.
1. Let _calendarOne_ be ? ToTemporalCalendarIdentifier(_one_).
1. Let _calendarTwo_ be ? ToTemporalCalendarIdentifier(_two_).
1. If _calendarOne_ is _calendarTwo_, return _two_.
1. If _calendarOne_ is *"iso8601"*, return _two_.
1. If _calendarTwo_ is *"iso8601"*, return _one_.
1. Throw a *RangeError* exception.
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal-isodaysinmonth" type="abstract operation">
<h1>
ISODaysInMonth (
Expand Down
14 changes: 0 additions & 14 deletions spec/plaindatetime.html
Original file line number Diff line number Diff line change
Expand Up @@ -463,20 +463,6 @@ <h1>Temporal.PlainDateTime.prototype.withPlainTime ( [ _plainTimeLike_ ] )</h1>
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal.plaindatetime.prototype.withplaindate">
<h1>Temporal.PlainDateTime.prototype.withPlainDate ( _plainDateLike_ )</h1>
<p>
This method performs the following steps when called:
</p>
<emu-alg>
1. Let _dateTime_ be the *this* value.
1. Perform ? RequireInternalSlot(_dateTime_, [[InitializedTemporalDateTime]]).
1. Let _plainDate_ be ? ToTemporalDate(_plainDateLike_).
1. Let _calendar_ be ? ConsolidateCalendars(_dateTime_.[[Calendar]], _plainDate_.[[Calendar]]).
1. Return ? CreateTemporalDateTime(_plainDate_.[[ISOYear]], _plainDate_.[[ISOMonth]], _plainDate_.[[ISODay]], _dateTime_.[[ISOHour]], _dateTime_.[[ISOMinute]], _dateTime_.[[ISOSecond]], _dateTime_.[[ISOMillisecond]], _dateTime_.[[ISOMicrosecond]], _dateTime_.[[ISONanosecond]], _calendar_).
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal.plaindatetime.prototype.withcalendar">
<h1>Temporal.PlainDateTime.prototype.withCalendar ( _calendarLike_ )</h1>
<p>
Expand Down
19 changes: 0 additions & 19 deletions spec/zoneddatetime.html
Original file line number Diff line number Diff line change
Expand Up @@ -672,25 +672,6 @@ <h1>Temporal.ZonedDateTime.prototype.withPlainTime ( [ _plainTimeLike_ ] )</h1>
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal.zoneddatetime.prototype.withplaindate">
<h1>Temporal.ZonedDateTime.prototype.withPlainDate ( _plainDateLike_ )</h1>
<p>
This method performs the following steps when called:
</p>
<emu-alg>
1. Let _zonedDateTime_ be the *this* value.
1. Perform ? RequireInternalSlot(_zonedDateTime_, [[InitializedTemporalZonedDateTime]]).
1. Let _plainDate_ be ? ToTemporalDate(_plainDateLike_).
1. Let _timeZoneRec_ be ? CreateTimeZoneMethodsRecord(_zonedDateTime_.[[TimeZone]], « ~get-offset-nanoseconds-for~, ~get-possible-instants-for~ »).
1. Let _instant_ be ! CreateTemporalInstant(_zonedDateTime_.[[Nanoseconds]]).
1. Let _plainDateTime_ be ? GetPlainDateTimeFor(_timeZoneRec_, _instant_, _zonedDateTime_.[[Calendar]]).
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. Set _instant_ to ? GetInstantFor(_timeZoneRec_, _resultPlainDateTime_, *"compatible"*).
1. Return ! CreateTemporalZonedDateTime(_instant_.[[Nanoseconds]], _timeZoneRec_.[[Receiver]], _calendar_).
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal.zoneddatetime.prototype.withtimezone">
<h1>Temporal.ZonedDateTime.prototype.withTimeZone ( _timeZoneLike_ )</h1>
<p>
Expand Down

0 comments on commit f7acbd2

Please sign in to comment.