Skip to content

Commit

Permalink
Remove absolute field
Browse files Browse the repository at this point in the history
Per 2020-07-31 meeting, removes the `absolute` field. Details:
* Changed `absolute` property getter to `toAbsolute()` method
* Stop accepting `absolute` in `from` and `with`.  Callers should use
  `Temporal.Absolute.toLocalDateTime` instead.
* Remove now-unneeded conflict handling in `from` and `with`
* Stop emitting `absolute` in `getFields()` and `getISOCalendarFields()`
* Updated TS types
* Ensure that object-returning methods returm new instances (for SES)
Changes above simplified things quite a bit. Removed over 100 LOC!
  • Loading branch information
justingrant committed Aug 10, 2020
1 parent 91650ed commit a39c10f
Show file tree
Hide file tree
Showing 14 changed files with 231 additions and 460 deletions.
2 changes: 1 addition & 1 deletion docs/cookbook/absoluteFromLegacyDate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const legacyDate = new Date('1970-01-01T00:00:01Z');

// Convert legacy Date to Temporal.Absolute
const absolute = Temporal.Absolute.fromEpochMilliseconds(legacyDate.getTime());
const ldt = Temporal.LocalDateTime.from({ absolute, timeZone: Temporal.now.timeZone() });
const ldt = absolute.toLocalDateTime(Temporal.now.timeZone());

assert(absolute instanceof Temporal.Absolute);
assert(ldt instanceof Temporal.LocalDateTime);
2 changes: 1 addition & 1 deletion docs/cookbook/getLocalizedArrival.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/
function getLocalizedArrival(parseableDeparture, flightTime, destinationTimeZone) {
const departure = Temporal.LocalDateTime.from(parseableDeparture);
const arrival = departure.absolute.plus(flightTime);
const arrival = departure.toAbsolute().plus(flightTime);
return arrival.toLocalDateTime(destinationTimeZone);
}

Expand Down
8 changes: 4 additions & 4 deletions docs/cookbook/getParseableZonedStringAtInstant.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ const result = absoluteTime.toString('Europe/Paris');
assert.equal(result, '2020-01-03T11:41:51+01:00[Europe/Paris]');
assert.equal(Temporal.Absolute.compare(absoluteTime, Temporal.Absolute.from(result)), 0);

const ldt = Temporal.LocalDateTime.from({ absolute: absoluteTime, timeZone: 'Europe/Paris' });
const ldt = absoluteTime.toLocalDateTime('Europe/Paris');
assert.equal(ldt.toString(), '2020-01-03T11:41:51+01:00[Europe/Paris]');
assert.equal(Temporal.Absolute.compare(absoluteTime, ldt.absolute), 0);
assert.equal(Temporal.Absolute.compare(absoluteTime, ldt.toAbsolute()), 0);
assert.equal(ldt.toDateTime().toString(), '2020-01-03T11:41:51');

// With an offset:

const result2 = absoluteTime.toString('-07:00');
const ldt2 = Temporal.LocalDateTime.from({ absolute: absoluteTime, timeZone: '-07:00' });
const ldt2 = absoluteTime.toLocalDateTime('-07:00');

assert.equal(result2, '2020-01-03T03:41:51-07:00');
assert.equal(ldt2.toString(), '2020-01-03T03:41:51-07:00[-07:00]');
Expand All @@ -27,7 +27,7 @@ assert.equal(ldt2.toString(), '2020-01-03T03:41:51-07:00[-07:00]');

const timeZone = Temporal.TimeZone.from('Asia/Seoul');
const result3 = absoluteTime.toString(timeZone);
const ldt3 = Temporal.LocalDateTime.from({ absolute: absoluteTime, timeZone: 'Asia/Seoul' });
const ldt3 = absoluteTime.toLocalDateTime('Asia/Seoul');

assert.equal(result3, '2020-01-03T19:41:51+09:00[Asia/Seoul]');
assert.equal(ldt3.toString(), '2020-01-03T19:41:51+09:00[Asia/Seoul]');
2 changes: 1 addition & 1 deletion docs/cookbook/getUtcOffsetDifferenceSecondsAtInstant.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function getUtcOffsetDifferenceSecondsAtInstant(source, targetTimeZone) {

const instant = Temporal.Absolute.from('2020-01-09T00:00Z');
const nyc = Temporal.TimeZone.from('America/New_York');
const ldtNyc = Temporal.LocalDateTime.from({ absolute: instant, timeZone: nyc });
const ldtNyc = instant.toLocalDateTime(nyc);
const chicago = Temporal.TimeZone.from('America/Chicago');

// At this instant, Chicago's local time is 3600 seconds earlier than New York
Expand Down
2 changes: 1 addition & 1 deletion docs/cookbook/getUtcOffsetSecondsAtInstant.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const ldt = Temporal.LocalDateTime.from({ absolute: '2020-01-09T00:00Z', timeZone: 'America/New_York' });
const ldt = Temporal.Absolute.from('2020-01-09T00:00Z').toLocalDateTime('America/New_York');

ldt.timeZoneOffsetNanoseconds / 1e9; // => -18000

Expand Down
2 changes: 1 addition & 1 deletion docs/cookbook/getUtcOffsetStringAtInstant.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const ldt = Temporal.LocalDateTime.from({ absolute: '2020-01-09T00:00Z', timeZone: 'America/New_York' });
const ldt = Temporal.Absolute.from('2020-01-09T00:00Z').toLocalDateTime('America/New_York');

ldt.timeZoneOffsetString; // => '-05:00'

Expand Down
250 changes: 80 additions & 170 deletions polyfill/lib/localdatetime.mjs

Large diffs are not rendered by default.

58 changes: 23 additions & 35 deletions polyfill/lib/poc/LocalDateTime.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@ import { Temporal } from '../..';
export declare type LocalDateTimeLike = Temporal.DateTimeLike & {
/**`Temporal.TimeZone`, IANA time zone identifier, or offset string */
timeZone?: Temporal.TimeZone | string;
/**`Temporal.Absolute` or ISO "Z" string */
absolute?: Temporal.Absolute | string;
/** Enables `from` using only local time values */
timeZoneOffsetNanoseconds?: number;
};
declare type LocalDateTimeFields = ReturnType<Temporal.DateTime['getFields']> & {
timeZone: Temporal.TimeZone;
absolute: Temporal.Absolute;
timeZoneOffsetNanoseconds: number;
};
declare type LocalDateTimeISOCalendarFields = ReturnType<Temporal.DateTime['getISOCalendarFields']> & {
timeZone: Temporal.TimeZone;
absolute: Temporal.Absolute;
timeZoneOffsetNanoseconds: number;
};
export interface OverflowOptions {
/**
Expand Down Expand Up @@ -86,22 +84,18 @@ export declare class LocalDateTime {
* Build a `Temporal.LocalDateTime` instance from one of the following:
* - Another LocalDateTime instance, in which case the result will deep-clone
* the input.
* - A "LocalDateTime-like" object with a `timeZone` field and either an
* `absolute` field OR `year`, `month`, and `day` fields. All non-required
* `Temporal.LocalDateTime` fields are accepted too, with the caveat that
* fields must be consistent. For example, if an object with `absolute` and
* `hours` is provided, then the `hours` value must match the `absolute` in
* the given time zone. Note: if neither `absolute` nor
* `timeZoneOffsetNanoseconds` are provided, then the time can be ambiguous
* around DST transitions. The `disambiguation` option can resolve this
* ambiguity.
* - A "LocalDateTime-like" property bag object with required properties
* `timeZone`, `year`, `month`, and `day`. Other fields (time fields and
* `timeZoneOffsetNanoseconds`) are optional. If `timeZoneOffsetNanoseconds`
* is not provided, then the time can be ambiguous around DST transitions.
* The `disambiguation` option can resolve this ambiguity.
* - An extended ISO 8601 string that includes a time zone identifier, e.g.
* `2007-12-03T10:15:30+01:00[Europe/Paris]`. If a timezone offset is not
* present, then the `disambiguation` option will be used to resolve any
* ambiguity. Note that an ISO string ending in "Z" (a UTC time) will not be
* accepted via a string parameter. Instead, the caller must explicitly
* opt-in to UTC using the object form `{absolute: isoString, timeZone:
* 'utc'}`
* opt-in to UTC, e.g.
* Temporal.Absolute.from(isoString).toLocalDateTime('UTC'}`
* - An object that can be converted to the string format above.
*
* If the input contains both a time zone offset and a time zone, in rare
Expand All @@ -127,44 +121,38 @@ export declare class LocalDateTime {
* is a "LocalDateTime-like" object. Accepted fields include:
* - All `Temporal.DateTime` fields, including `calendar`
* - `timeZone` as a time zone identifier string like `Europe/Paris` or a
* `Temporal.TimeZone` instance
* - `absolute` as an ISO 8601 string ending in "Z" or an `Temporal.Absolute`
* instance
* `Temporal.TimeZone` instance
* - `timezoneOffsetNanoseconds`
*
* If the `absolute` field is included, all other input fields must be
* consistent with this value or this method will throw.
*
* If the `timeZone` field is included, `with` will first convert all existing
* fields to the new time zone and then fields in the input will be played on
* top of the new time zone. Therefore, `.with({timeZone})` is an easy way to
* convert to a new time zone while updating the clock time. However, to keep
* clock time as-is while resetting the time zone, the current fields must be
* spread into the new time zone. Examples:
* clock time as-is while resetting the time zone, use the `toDateTime()`
* method. Examples:
* ```
* const sameInstantInOtherTz = ldt.with({timeZone: 'Europe/London'});
* const newTzSameLocalTime = ldt.with({...ldt.getFields(), timeZone: 'Europe/London'});
* const newTzSameLocalTime = ldt.toDateTime().toLocalDateTime('Europe/London');
* ```
*
* If the `timezoneOffsetNanoseconds` field is provided, then it's possible
* for it to conflict with the input object's `timeZone` property or, if
* omitted, the object's existing time zone. The `offset` option (which
* defaults to `'prefer'`) will resolve the conflict. However, if both
* `absolute` and `timezoneOffsetNanoseconds` fields are included and they
* conflict, then a `RangeError` will be thrown.
* defaults to `'prefer'`) will resolve the conflict.
*
* If the `timezoneOffsetNanoseconds` field is not provided, but the
* `absolute` nor the `timeZone` fields are not provided either, then the
* existing `timezoneOffsetNanoseconds` field will be used by `with` as if it
* had been provided by the caller. By default, this will prefer the existing
* offset when resolving ambiguous results. For example, if a
* `timeZone` field is not provided either, then the existing
* `timezoneOffsetNanoseconds` field will be used by `with` as if it had been
* provided by the caller. By default, this will prefer the existing offset
* when resolving ambiguous results. For example, if a
* `Temporal.LocalDateTime` is set to the "second" 1:30AM on a day where the
* 1-2AM clock hour is repeated after a backwards DST transition, then calling
* `.with({minute: 45})` will result in an ambiguity which is resolved using
* the default `offset: 'prefer'` option. Because the existing offset is valid
* for the new time, it will be retained so the result will be the "second"
* 1:45AM. However, if the existing offset is not valid for the new result
* (e.g. `.with({hour: 0})`), then the offset will be changed.
* (e.g. `.with({hour: 0})`), then the default behavior will change the
* offset.
*
* Available options:
* ```
Expand Down Expand Up @@ -195,7 +183,7 @@ export declare class LocalDateTime {
* will automatically convert it to a JSON-friendly ISO 8601 string (ending in
* `Z`) when persisting to JSON.
*/
get absolute(): Temporal.Absolute;
toAbsolute(): Temporal.Absolute;
/**
* Returns the `Temporal.TimeZone` representing this object's time zone.
*
Expand Down Expand Up @@ -280,7 +268,7 @@ export declare class LocalDateTime {
*
* The resulting object includes all fields returned by
* `Temporal.DateTime.prototype.getFields()`, as well as `timeZone`,
* and `absolute`.
* and `timeZoneOffsetNanoseconds`.
*
* The result of this method can be used for round-trip serialization via
* `from()`, `with()`, or `JSON.stringify`.
Expand Down Expand Up @@ -310,7 +298,7 @@ export declare class LocalDateTime {
* Returns `true` if both the absolute timestamp and time zone are identical
* to the other `Temporal.LocalDateTime` instance, and `false` otherwise. To
* compare only the absolute timestamps and ignore time zones, use
* `.absolute.compare()`.
* `.toAbsolute().compare()`.
*/
equals(other: LocalDateTime): boolean;
/**
Expand Down
7 changes: 3 additions & 4 deletions polyfill/lib/poc/LocalDateTime.nocomments.d.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { Temporal } from '../..';
export declare type LocalDateTimeLike = Temporal.DateTimeLike & {
timeZone?: Temporal.TimeZone | string;
absolute?: Temporal.Absolute | string;
timeZoneOffsetNanoseconds?: number;
};
declare type LocalDateTimeFields = ReturnType<Temporal.DateTime['getFields']> & {
timeZone: Temporal.TimeZone;
absolute: Temporal.Absolute;
timeZoneOffsetNanoseconds: number;
};
declare type LocalDateTimeISOCalendarFields = ReturnType<Temporal.DateTime['getISOCalendarFields']> & {
timeZone: Temporal.TimeZone;
absolute: Temporal.Absolute;
timeZoneOffsetNanoseconds: number;
};
export interface OverflowOptions {
overflow: 'constrain' | 'reject';
Expand All @@ -36,7 +35,7 @@ export declare class LocalDateTime {
): LocalDateTime;
with(localDateTimeLike: LocalDateTimeLike, options?: LocalDateTimeAssignmentOptions): LocalDateTime;
withCalendar(calendar: Temporal.CalendarProtocol): LocalDateTime;
get absolute(): Temporal.Absolute;
toAbsolute(): Temporal.Absolute;
get timeZone(): Temporal.TimeZone;
get calendar(): Temporal.CalendarProtocol;
toDateTime(): Temporal.DateTime;
Expand Down
10 changes: 5 additions & 5 deletions polyfill/lib/poc/LocalDateTime.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ describe('LocalDateTime', () => {

it('Samoa date line change: 10:00PM 29 Dec 2011 -> 11:00PM 31 Dec 2011', () => {
const dayBeforeSamoaDateLineChangeAbs = new Temporal.DateTime(2011, 12, 29, 22).toAbsolute('Pacific/Apia');
const start = LocalDateTime.from({ absolute: dayBeforeSamoaDateLineChangeAbs, timeZone: 'Pacific/Apia' });
const start = dayBeforeSamoaDateLineChangeAbs.toLocalDateTime('Pacific/Apia');
const added = start.plus({ days: 1, hours: 1 });
equal(added.day, 31);
equal(added.hour, 23);
Expand Down Expand Up @@ -800,8 +800,8 @@ describe('LocalDateTime', () => {
it('LocalDateTime.prototype.toJSON is a Function', () => {
equal(typeof LocalDateTime.prototype.toJSON, 'function');
});
it('LocalDateTime.prototype has absolute', () => {
assert('absolute' in LocalDateTime.prototype);
it('LocalDateTime.prototype has toAbsolute', () => {
assert('toAbsolute' in LocalDateTime.prototype);
});
it('LocalDateTime.prototype has timeZone', () => {
assert('timeZone' in LocalDateTime.prototype);
Expand Down Expand Up @@ -833,11 +833,11 @@ describe('LocalDateTime', () => {
assert(instant);
equal(typeof instant, 'object');
equal(
instant.absolute.getEpochSeconds(),
instant.toAbsolute().getEpochSeconds(),
Math.floor(Date.UTC(1976, 10, 18, 15, 23, 30, 123) / 1e3),
'getEpochSeconds'
);
equal(instant.absolute.getEpochMilliseconds(), Date.UTC(1976, 10, 18, 15, 23, 30, 123), 'getEpochMilliseconds');
equal(instant.toAbsolute().getEpochMilliseconds(), Date.UTC(1976, 10, 18, 15, 23, 30, 123), 'getEpochMilliseconds');

describe('LocalDateTime for (1976, 11, 18, 15, 23, 30, 123, 456, 789)', () => {
it('datetime can be constructed', () => {
Expand Down
Loading

0 comments on commit a39c10f

Please sign in to comment.