Skip to content

Commit

Permalink
Allow passing in plain objects with calendar methods
Browse files Browse the repository at this point in the history
The other half of the custom time zones and calendars protocol discussed
in #300 was allowing calendars and time zones to be plain objects with
the appropriate methods on them.

This adds a test verifying that it's possible to use a plain object with
calendar methods as a time zone, and makes the changes needed to allow
that.
  • Loading branch information
ptomato committed Jun 9, 2020
1 parent ef7bf89 commit 9bbe2c6
Show file tree
Hide file tree
Showing 17 changed files with 349 additions and 67 deletions.
4 changes: 2 additions & 2 deletions docs/absolute.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,11 @@ Same as `getEpochSeconds()`, but with nanosecond (10<sup>&minus;9</sup> second)

The value returned from this method is suitable to be passed to `new Temporal.Absolute()`.

### absolute.**inTimeZone**(_timeZone_: object | string, _calendar_?: Temporal.Calendar | string) : Temporal.DateTime
### absolute.**inTimeZone**(_timeZone_: object | string, _calendar_?: object | string) : Temporal.DateTime

**Parameters:**
- `timeZone` (object or string): A `Temporal.TimeZone` object, or an object implementing the [time zone protocol](./timezone.md#protocol), or a string description of the time zone; either its IANA name or UTC offset.
- `calendar` (optional object or string): A `Temporal.Calendar` object, or a calendar identifier.
- `calendar` (optional object or string): A `Temporal.Calendar` object, or a plain object, or a calendar identifier.
The default is to use the ISO 8601 calendar.

**Returns:** a `Temporal.DateTime` object indicating the calendar date and wall-clock time in `timeZone`, according to the reckoning of `calendar`, at the absolute time indicated by `absolute`.
Expand Down
10 changes: 9 additions & 1 deletion docs/calendar.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ For specialized applications where you need to do calculations in a calendar sys
To do this, create a class inheriting from `Temporal.Calendar`, call `super()` in the constructor with a calendar identifier, and implement all the methods.
Any subclass of `Temporal.Calendar` will be accepted in Temporal APIs where a built-in `Temporal.Calendar` would work.

### Protocol

It's also possible for a plain object to be a custom calendar, without subclassing.
The object must implement the `Temporal.Calendar` methods and have an `id` property.
It is possible to pass such an object into any Temporal API that would normally take a built-in `Temporal.Calendar`.

## Constructor

### **new Temporal.Calendar**(_calendarIdentifier_: string) : Temporal.Calendar
Expand Down Expand Up @@ -97,8 +103,10 @@ cal = Temporal.Calendar.from('2020-01-13T16:31:00.065858086-08:00[America/Vancou
// Existing calendar object
cal2 = Temporal.Calendar.from(cal);

// Custom calendar that is a plain object (this calendar does not do much)
cal = Temporal.Calendar.from({id: 'mycalendar'});

/*⚠️*/ cal = Temporal.Calendar.from('discordian'); // not a built-in calendar, throws
/*⚠️*/ cal = Temporal.Calendar.from({id: 'iso8601'}); // not a Calendar object, throws
/*⚠️*/ cal = Temporal.Calendar.from('[c=iso8601]'); // lone annotation not a valid ISO 8601 string
```

Expand Down
12 changes: 6 additions & 6 deletions docs/date.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ A `Temporal.Date` can be converted into a `Temporal.DateTime` by combining it wi

## Constructor

### **new Temporal.Date**(_isoYear_: number, _isoMonth_: number, _isoDay_: number, _calendar_?: Temporal.Calendar) : Temporal.Date
### **new Temporal.Date**(_isoYear_: number, _isoMonth_: number, _isoDay_: number, _calendar_?: object) : Temporal.Date

**Parameters:**
- `isoYear` (number): A year.
- `isoMonth` (number): A month, ranging between 1 and 12 inclusive.
- `isoDay` (number): A day of the month, ranging between 1 and 31 inclusive.
- `calendar` (optional `Temporal.Calendar`): A calendar to project the date into.
- `calendar` (optional `Temporal.Calendar` or plain object): A calendar to project the date into.

**Returns:** a new `Temporal.Date` object.

Expand Down Expand Up @@ -145,7 +145,7 @@ date.month // => 8
date.day // => 24
```

### date.**calendar** : Temporal.Calendar
### date.**calendar** : object

The `calendar` read-only property gives the calendar that the `year`, `month`, and `day` properties are interpreted in.

Expand Down Expand Up @@ -269,10 +269,10 @@ date.with({day: 1}); // => 2006-01-01
date.plus({months: 1}).with({day: date.daysInMonth}); // => 2006-02-28
```

### date.**withCalendar**(_calendar_: Temporal.Calendar | string) : Temporal.Date
### date.**withCalendar**(_calendar_: object | string) : Temporal.Date

**Parameters:**
- `calendar` (`Temporal.Calendar` or string): The calendar into which to project `date`.
- `calendar` (`Temporal.Calendar` or plain object or string): The calendar into which to project `date`.

**Returns:** a new `Temporal.Date` object which is the date indicated by `date`, projected into `calendar`.

Expand Down Expand Up @@ -530,7 +530,7 @@ date.getYearMonth() // => 2006-08
date.getMonthDay() // => 08-24
```

### date.**getFields**() : { year: number, month: number, day: number, calendar: Temporal.Calendar, [propName: string]: unknown }
### date.**getFields**() : { year: number, month: number, day: number, calendar: object, [propName: string]: unknown }

**Returns:** a plain object with properties equal to the fields of `date`.

Expand Down
12 changes: 6 additions & 6 deletions docs/datetime.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ A `Temporal.DateTime` can also be converted into any of the other `Temporal` obj

## Constructor

### **new Temporal.DateTime**(_isoYear_: number, _isoMonth_: number, _isoDay_: number, _hour_: number = 0, _minute_: number = 0, _second_: number = 0, _millisecond_: number = 0, _microsecond_: number = 0, _nanosecond_: number = 0, _calendar_?: Temporal.Calendar) : Temporal.DateTime
### **new Temporal.DateTime**(_isoYear_: number, _isoMonth_: number, _isoDay_: number, _hour_: number = 0, _minute_: number = 0, _second_: number = 0, _millisecond_: number = 0, _microsecond_: number = 0, _nanosecond_: number = 0, _calendar_?: object) : Temporal.DateTime

**Parameters:**
- `isoYear` (number): A year.
Expand All @@ -33,7 +33,7 @@ A `Temporal.DateTime` can also be converted into any of the other `Temporal` obj
- `millisecond` (optional number): A number of milliseconds, ranging between 0 and 999 inclusive.
- `microsecond` (optional number): A number of microseconds, ranging between 0 and 999 inclusive.
- `nanosecond` (optional number): A number of nanoseconds, ranging between 0 and 999 inclusive.
- `calendar` (optional `Temporal.Calendar`): A calendar to project the date into.
- `calendar` (optional `Temporal.Calendar` or plain object): A calendar to project the date into.

**Returns:** a new `Temporal.DateTime` object.

Expand Down Expand Up @@ -205,7 +205,7 @@ dt.microsecond // => 3
dt.nanosecond // => 500
```

### datetime.**calendar** : Temporal.Calendar
### datetime.**calendar** : object

The `calendar` read-only property gives the calendar that the `year`, `month`, and `day` properties are interpreted in.

Expand Down Expand Up @@ -326,10 +326,10 @@ dt = new Temporal.DateTime(1995, 12, 7, 3, 24, 30, 0, 3, 500);
dt.with({year: 2015, second: 31}) // => 2015-12-07T03:24:31.000003500
```

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

**Parameters:**
- `calendar` (`Temporal.Calendar` or string): The calendar into which to project `datetime`.
- `calendar` (`Temporal.Calendar` or plain object or string): The calendar into which to project `datetime`.

**Returns:** a new `Temporal.DateTime` object which is the date indicated by `datetime`, projected into `calendar`.

Expand Down Expand Up @@ -604,7 +604,7 @@ dt.getMonthDay() // => 12-07
dt.getTime() // => 03:24:30.000003500
```

### datetime.**getFields**() : { year: number, month: number, day: number, hour: number, minute: number, second: number, millisecond: number, microsecond: number, nanosecond: number, calendar: Temporal.Calendar, [propName: string]: unknown }
### datetime.**getFields**() : { year: number, month: number, day: number, hour: number, minute: number, second: number, millisecond: number, microsecond: number, nanosecond: number, calendar: object, [propName: string]: unknown }

**Returns:** a plain object with properties equal to the fields of `datetime`.

Expand Down
8 changes: 4 additions & 4 deletions docs/monthday.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ A `Temporal.MonthDay` can be converted into a `Temporal.Date` by combining it wi

## Constructor

### **new Temporal.MonthDay**(_isoMonth_: number, _isoDay_: number, _calendar_?: Temporal.Calendar, _refISOYear_?: number) : Temporal.MonthDay
### **new Temporal.MonthDay**(_isoMonth_: number, _isoDay_: number, _calendar_?: object, _refISOYear_?: number) : Temporal.MonthDay

**Parameters:**
- `isoMonth` (number): A month, ranging between 1 and 12 inclusive.
- `isoDay` (number): A day of the month, ranging between 1 and 31 inclusive.
- `calendar` (optional `Temporal.Calendar`): A calendar to project the date into.
- `calendar` (optional `Temporal.Calendar` or plain object): A calendar to project the date into.
- `refISOYear` (optional number): A reference year, used for disambiguation when implementing other calendar systems.
The default is the first leap year after the [Unix epoch](https://en.wikipedia.org/wiki/Unix_time).
You can omit this parameter unless using a non-ISO-8601 calendar.
Expand Down Expand Up @@ -112,7 +112,7 @@ md.month // => 8
md.day // => 24
```

### monthDay.**calendar** : Temporal.Calendar
### monthDay.**calendar** : object

The `calendar` read-only property gives the calendar that the `month` and `day` properties are interpreted in.

Expand Down Expand Up @@ -272,7 +272,7 @@ md.withYear(2020) // => 2020-02-29

In calendars where more information than just the year is needed to convert a `Temporal.MonthDay` to a `Temporal.Date`, you can pass an object to `withYear()` that contains the necessary properties.

### monthDay.**getFields**() : { month: number, day: number, calendar: Temporal.Calendar, [propName: string]: unknown }
### monthDay.**getFields**() : { month: number, day: number, calendar: object, [propName: string]: unknown }

**Returns:** a plain object with properties equal to the fields of `monthDay`.

Expand Down
8 changes: 4 additions & 4 deletions docs/now.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ nextTransition.inTimeZone(tz);
// On 2020-03-08T03:00 the clock will change from UTC -08:00 to -07:00
```

### Temporal.now.**dateTime**(_timeZone_: object | string = Temporal.now.timeZone(), _calendar_: Temporal.Calendar | string = 'iso8601') : Temporal.DateTime
### Temporal.now.**dateTime**(_timeZone_: object | string = Temporal.now.timeZone(), _calendar_: object | string = 'iso8601') : Temporal.DateTime

**Parameters:**
- `timeZone` (optional object or string): The time zone to get the current date and time in, as a `Temporal.TimeZone` object, an object implementing the [time zone protocol](./timezone.md#protocol), or a string.
If not given, the current system time zone will be used.
- `calendar` (optional `Temporal.Calendar` or string): The calendar system to get the current date and time in.
- `calendar` (optional `Temporal.Calendar`, plain object, or string): The calendar system to get the current date and time in.
If not given, the ISO 8601 calendar will be used.

**Returns:** a `Temporal.DateTime` object representing the current system date and time.
Expand All @@ -85,12 +85,12 @@ Object.entries(financialCentres).forEach(([name, timeZone]) => {
// Tokyo: 2020-01-25T14:52:14.759534758
```

### Temporal.now.**date**(_timeZone_: object | string = Temporal.now.timeZone(), _calendar_: Temporal.Calendar | string = 'iso8601') : Temporal.Date
### Temporal.now.**date**(_timeZone_: object | string = Temporal.now.timeZone(), _calendar_: object | string = 'iso8601') : Temporal.Date

**Parameters:**
- `timeZone` (optional object or string): The time zone to get the current date and time in, as a `Temporal.TimeZone` object, an object implementing the [time zone protocol](./timezone.md#protocol), or a string.
If not given, the current system time zone will be used.
- `calendar` (optional `Temporal.Calendar` or string): The calendar system to get the current date and time in.
- `calendar` (optional `Temporal.Calendar`, plain object, or string): The calendar system to get the current date and time in.
If not given, the ISO 8601 calendar will be used.

**Returns:** a `Temporal.Date` object representing the current system date.
Expand Down
4 changes: 2 additions & 2 deletions docs/timezone.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,11 @@ tz = new Temporal.TimeZone('-08:00');
tz.getOffsetStringFor(timestamp); // => -08:00
```

### timeZone.**getDateTimeFor**(_absolute_: Temporal.Absolute, _calendar_?: Temporal.Calendar | string) : Temporal.DateTime
### timeZone.**getDateTimeFor**(_absolute_: Temporal.Absolute, _calendar_?: object | string) : Temporal.DateTime

**Parameters:**
- `absolute` (`Temporal.Absolute`): An absolute time to convert.
- `calendar` (optional object or string): A `Temporal.Calendar` object, or a calendar identifier.
- `calendar` (optional object or string): A `Temporal.Calendar` object, or a plain object, or a calendar identifier.
The default is to use the ISO 8601 calendar.

**Returns:** A `Temporal.DateTime` object indicating the calendar date and wall-clock time in `timeZone`, according to the reckoning of `calendar`, at the absolute time indicated by `absolute`.
Expand Down
8 changes: 4 additions & 4 deletions docs/yearmonth.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ A `Temporal.YearMonth` can be converted into a `Temporal.Date` by combining it w

## Constructor

### **new Temporal.YearMonth**(_isoYear_: number, _isoMonth_: number, _calendar_?: Temporal.Calendar, _refISODay_: number = 1) : Temporal.YearMonth
### **new Temporal.YearMonth**(_isoYear_: number, _isoMonth_: number, _calendar_?: object, _refISODay_: number = 1) : Temporal.YearMonth

**Parameters:**
- `isoYear` (number): A year.
- `isoMonth` (number): A month, ranging between 1 and 12 inclusive.
- `calendar` (optional `Temporal.Calendar`): A calendar to project the month into.
- `calendar` (optional `Temporal.Calendar` or plain object): A calendar to project the month into.
- `refISODay` (optional number): A reference day, used for disambiguation when implementing other calendar systems.
You can omit this parameter unless using a non-ISO-8601 calendar.

Expand Down Expand Up @@ -136,7 +136,7 @@ ym.year // => 2019
ym.month // => 6
```

### yearMonth.**calendar** : Temporal.Calendar
### yearMonth.**calendar** : object

The `calendar` read-only property gives the calendar that the `year` and `month` properties are interpreted in.

Expand Down Expand Up @@ -438,7 +438,7 @@ ym = Temporal.YearMonth.from('2019-06');
ym.withDay(24) // => 2019-06-24
```

### yearMonth.**getFields**() : { year: number, month: number, calendar: Temporal.Calendar, [propName: string]: unknown }
### yearMonth.**getFields**() : { year: number, month: number, calendar: object, [propName: string]: unknown }

**Returns:** a plain object with properties equal to the fields of `yearMonth`.

Expand Down
Loading

0 comments on commit 9bbe2c6

Please sign in to comment.