Skip to content

Commit

Permalink
Default Date.toDateTime() argument to midnight
Browse files Browse the repository at this point in the history
This arises from a need identified in feedback to have a more ergonomic
way to get a Temporal.DateTime with midnight on a certain date.

Closes: #737
  • Loading branch information
ptomato authored and ryzokuken committed Aug 31, 2020
1 parent 05b0d41 commit 3159912
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 12 deletions.
2 changes: 1 addition & 1 deletion docs/cookbook/storageTank.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

// Show data starting from the most recent midnight in the tank's location (Stockholm)
const tankTimeZone = Temporal.TimeZone.from('Europe/Stockholm');
const tankMidnight = Temporal.now.dateTime(tankTimeZone).with(Temporal.Time.from('00:00')).toAbsolute(tankTimeZone);
const tankMidnight = Temporal.now.date(tankTimeZone).toDateTime().toAbsolute(tankTimeZone);
const atOrAfterMidnight = (x) => Temporal.Absolute.compare(x, tankMidnight) >= 0;
const dataStartIndex = tankDataX.findIndex(atOrAfterMidnight);
const labelFormatter = new Intl.DateTimeFormat(undefined, {
Expand Down
14 changes: 8 additions & 6 deletions docs/date.md
Original file line number Diff line number Diff line change
Expand Up @@ -405,9 +405,9 @@ other.difference(date, { largestUnit: 'years' }) // => throws RangeError
// If you really need to calculate the difference between two Dates in
// hours, you can eliminate the ambiguity by explicitly choosing the
// point in time from which you want to reckon the difference. For
// example, using midnight:
midnight = Temporal.Time.from('00:00');
date.toDateTime(midnight).difference(other.toDateTime(midnight), { largestUnit: 'hours' })
// example, using noon:
noon = Temporal.Time.from('12:00');
date.toDateTime(noon).difference(other.toDateTime(noon), { largestUnit: 'hours' })
// => PT109032H
```

Expand Down Expand Up @@ -510,23 +510,25 @@ This method overrides `Object.prototype.valueOf()` and always throws an exceptio
This is because it's not possible to compare `Temporal.Date` objects with the relational operators `<`, `<=`, `>`, or `>=`.
Use `Temporal.Date.compare()` for this, or `date.equals()` for equality.

### date.**toDateTime**(_time_: Temporal.Time) : Temporal.DateTime
### date.**toDateTime**(_time_?: Temporal.Time) : Temporal.DateTime

**Parameters:**
- `time` (`Temporal.Time`): A time of day on `date`.
- `time` (optional `Temporal.Time`): A time of day on `date`.

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

This method can be used to convert `Temporal.Date` into a `Temporal.DateTime`, by supplying the time of day to use.
The default `time`, if it is not given, is midnight (00:00).
The converted object carries a copy of all the relevant fields of `date` and `time`.

This is exactly equivalent to [`time.toDateTime(date)`](./time.html#toDateTime).
If `time` is given, this is exactly equivalent to [`time.toDateTime(date)`](./time.html#toDateTime).

Usage example:
```javascript
date = Temporal.Date.from('2006-08-24');
time = Temporal.Time.from('15:23:30.003');
date.toDateTime(time) // => 2006-08-24T15:23:30.003
date.toDateTime() // => 2006-08-24T00:00
```

### date.**toYearMonth**() : Temporal.YearMonth
Expand Down
9 changes: 6 additions & 3 deletions polyfill/lib/date.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -201,20 +201,23 @@ export class Date {
valueOf() {
throw new TypeError('use compare() or equals() to compare Temporal.Date');
}
toDateTime(temporalTime) {
toDateTime(temporalTime = undefined) {
if (!ES.IsTemporalDate(this)) throw new TypeError('invalid receiver');
if (!ES.IsTemporalTime(temporalTime)) throw new TypeError('invalid Temporal.Time object');
const year = GetSlot(this, ISO_YEAR);
const month = GetSlot(this, ISO_MONTH);
const day = GetSlot(this, ISO_DAY);
const calendar = GetSlot(this, CALENDAR);
const DateTime = GetIntrinsic('%Temporal.DateTime%');

if (!temporalTime) return new DateTime(year, month, day, 0, 0, 0, 0, 0, 0, calendar);

if (!ES.IsTemporalTime(temporalTime)) throw new TypeError('invalid Temporal.Time object');
const hour = GetSlot(temporalTime, HOUR);
const minute = GetSlot(temporalTime, MINUTE);
const second = GetSlot(temporalTime, SECOND);
const millisecond = GetSlot(temporalTime, MILLISECOND);
const microsecond = GetSlot(temporalTime, MICROSECOND);
const nanosecond = GetSlot(temporalTime, NANOSECOND);
const DateTime = GetIntrinsic('%Temporal.DateTime%');
return new DateTime(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, calendar);
}
toYearMonth() {
Expand Down
3 changes: 3 additions & 0 deletions polyfill/test/date.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ describe('Date', () => {
throws(() => date.toDateTime({ hour: 11, minute: 30, second: 23 }), TypeError);
throws(() => date.toDateTime('11:30:23'), TypeError);
});
it('optional argument defaults to midnight', () => {
equal(`${date.toDateTime()}`, '1976-11-18T00:00');
});
});
describe('date.difference() works', () => {
const date = new Date(1976, 11, 18);
Expand Down
6 changes: 4 additions & 2 deletions spec/date.html
Original file line number Diff line number Diff line change
Expand Up @@ -394,14 +394,16 @@ <h1>Temporal.Date.prototype.equals ( _other_ )</h1>
</emu-clause>

<emu-clause id="sec-temporal.date.prototype.todatetime">
<h1>Temporal.Date.prototype.toDateTime ( _temporalTime_ )</h1>
<h1>Temporal.Date.prototype.toDateTime ( [ _temporalTime_ ] )</h1>
<p>
The `toDateTime` method takes one argument _temporalTime_.
The `toDateTime` method takes one optional argument _temporalTime_.
The following steps are taken:
</p>
<emu-alg>
1. Let _temporalDate_ be the *this* value.
1. Perform ? RequireInternalSlot(_temporalDate_, [[InitializedTemporalDate]]).
1. If _temporalTime_ is *undefined*, then
1. Return ? CreateTemporalDateTime(_temporalDate_.[[ISOYear]], _temporalDate.[[ISOMonth]], _temporalDate_.[[ISODay]], 0, 0, 0, 0, 0, 0).
1. Perform ? RequireInternalSlot(_temporalTime_, [[InitializedTemporalTime]]).
1. Return ? CreateTemporalDateTime(_temporalDate_.[[ISOYear]], _temporalDate_.[[ISOMonth]], _temporalDate_.[[ISODay]],
_temporalTime_.[[Hour]], _temporalTime_.[[Minute]], _temporalTime_.[[Second]],
Expand Down

0 comments on commit 3159912

Please sign in to comment.