Skip to content

Editorial and docs updates #3073

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ See [Calendars in Temporal](./calendars.md) for detailed documentation.

All `Temporal` types have a string representation for persistence and interoperability.
The correspondence between types and machine-readable strings is shown below.
For more information about string parsing, serialization, and formatting in `Temporal` (including how Temporal is using industry standards like ISO 8601 and RFC 3339), see [String Parsing, Serialization, and Formatting](./strings.md).
For more information about string parsing, serialization, and formatting in `Temporal` (including how Temporal is using industry standards like ISO 8601, RFC 3339, and RFC 9557), see [String Parsing, Serialization, and Formatting](./strings.md).

<img src="persistence-model.svg">

Expand Down
2 changes: 1 addition & 1 deletion docs/cookbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ Sorting other `Temporal` types would work exactly the same way.

### Sort ISO date/time strings

Sort a list of ISO 8601 date/time strings, for example to place log entries in order.
Sort a list of ISO 8601 or RFC 9557 date/time strings, for example to place log entries in order.

<!-- prettier-ignore-start -->
```javascript
Expand Down
29 changes: 19 additions & 10 deletions docs/cookbook/futureDateForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,26 @@
const params = new URL(document.location).searchParams;
const futuredateParam = params.get('futuredate');

// If you have Intl.DurationFormat, then you can do this with
// until.toLocaleString() and untilMonths.toLocaleString(). This
// example will be updated when that becomes possible. For now, we can
// generate the string only in English.
// Workaround to generate the string if the browser does not have
// Intl.DurationFormat. The workaround works only in English.
function englishPlural(n, singular, plural) {
return `${n} ${n === 1 ? singular : plural}`;
}
function formatDays(duration) {
if (typeof Intl.DurationFormat === 'undefined') {
return englishPlural(duration.days, 'day', 'days');
}
return duration.toLocaleString();
}
function formatMonths(duration) {
if (typeof Intl.DurationFormat === 'undefined') {
return (
`${englishPlural(duration.months, 'month', 'months')}` +
(duration.days !== 0 ? `, ${englishPlural(duration.days, 'day', 'days')}` : '')
);
}
return duration.toLocaleString();
}

// When form data posted:
if (futuredateParam !== null) {
Expand All @@ -18,18 +31,14 @@ if (futuredateParam !== null) {
const until = today.until(futureDate, { largestUnit: 'day' });
const untilMonths = until.round({ largestUnit: 'month', relativeTo: today });

const dayString = englishPlural(until.days, 'day', 'days');
const monthString =
`${englishPlural(untilMonths.months, 'month', 'months')}` +
(untilMonths.days !== 0 ? `, ${englishPlural(untilMonths.days, 'day', 'days')}` : '');

const dayString = formatDays(until);
const results = document.getElementById('futuredate-results');
results.innerHTML = `
<p>From and including: <strong>${today.toLocaleString()}</strong></p>
<p>To but not including: <strong>${futureDate.toLocaleString()}</strong></p>
<h4>Result: ${dayString}</h4>
<p>It is ${dayString} from the start date to the end date, but not
including the end date.</p>
<p>Or ${monthString} excluding the end date.</p>
<p>Or ${formatMonths(untilMonths)} excluding the end date.</p>
`;
}
2 changes: 0 additions & 2 deletions docs/cookbook/getElapsedDurationSinceInstant.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,4 @@ assert.equal(`${result2}`, 'PT240M');
// Example of using it in a countdown:

const duration = Temporal.Now.instant().until(Temporal.Instant.from('2020-04-01T13:00-07:00[America/Los_Angeles]'));
// Note that this does not work unless you have Intl.DurationFormat, which is
// still an early-stage proposal.
`It's ${duration.toLocaleString()} ${duration.sign < 0 ? 'until' : 'since'} the TC39 Temporal presentation`;
1 change: 0 additions & 1 deletion docs/duration.md
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,6 @@ This method overrides `Object.prototype.toLocaleString()` to provide a human-rea
The `locales` and `options` arguments are the same as in the constructor to [`Intl.DurationFormat`](http://tc39.es/proposal-intl-duration-format/).

> **NOTE**: This method requires that your JavaScript environment supports `Intl.DurationFormat`.
> That is still an early-stage proposal and at the time of writing it is not supported anywhere.
> If `Intl.DurationFormat` is not available, then the output of this method is the same as that of `duration.toString()`, and the `locales` and `options` arguments are ignored.

Usage examples:
Expand Down
13 changes: 9 additions & 4 deletions docs/plaindate.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,17 @@ If the value is any other object, it:
- Must have either a number `month` property or a string `monthCode` property.
- May have a `calendar` property. If omitted, the [ISO 8601 calendar](https://en.wikipedia.org/wiki/ISO_8601#Dates) will be used by default.

If the value is not an object, it must be a string, which is expected to be in ISO 8601 format.
If the value is not an object, it must be a string, which is expected to be in RFC 9557 format, or a subset of that format that includes at least the date portion.
Any time part is optional and will be ignored.
Time zone or UTC offset information will also be ignored, with one exception: if a string contains a `Z` in place of a numeric UTC offset, then a `RangeError` will be thrown because interpreting these strings as a local date and time is usually a bug. `Temporal.Instant.from` should be used instead to parse these strings, and the result's `toZonedDateTimeISO` method can be used to obtain a timezone-local date and time.

Note that ISO 8601 and RFC 3339 formats are also subsets of RFC 9557, so will also work.
Temporal additionally accepts a few ISO 8601 extensions that RFC 9557 does not, like the use of 6-digit years.
For more info, see [RFC 9557 / ISO 8601 Grammar](https://tc39.es/proposal-temporal/#sec-temporal-iso8601grammar).

In unusual cases of needing date or time components of `Z`-terminated timestamp strings (e.g. daily rollover of a UTC-timestamped log file), use the time zone `'UTC'`. For example, the following code returns a "UTC date": `Temporal.Instant.from(item).toZonedDateTimeISO('UTC').toPlainDate()`.

If the string isn't valid according to ISO 8601, then a `RangeError` will be thrown regardless of the value of `overflow`.
If the string isn't a valid subset of the RFC 9557 format, then a `RangeError` will be thrown regardless of the value of `overflow`.

The `overflow` option works as follows, if `item` is an object:

Expand Down Expand Up @@ -641,13 +645,14 @@ date.equals(date); // => true
Valid values are `'auto'`, `'always'`, `'never'`, and `'critical'`.
The default is `'auto'`.

**Returns:** a string in the ISO 8601 date format representing `date`.
**Returns:** a string in the RFC 9557 date format representing `date`.

This method overrides the `Object.prototype.toString()` method and provides a convenient, unambiguous string representation of `date`.
The string can be passed to `Temporal.PlainDate.from()` to create a new `Temporal.PlainDate` object.

Normally, a calendar annotation is shown when `date`'s calendar is not the ISO 8601 calendar.
By setting the `calendarName` option to `'always'` or `'never'` this can be overridden to always or never show the annotation, respectively.
With `calendarName: 'never'` the returned string will additionally be valid in the ISO 8601 and RFC 3339 date formats.
Normally not necessary, a value of `'critical'` is equivalent to `'always'` but the annotation will contain an additional `!` for certain interoperation use cases.
For more information on the calendar annotation, see [the `Temporal` string formats documentation](./strings.md#calendar-systems).

Expand Down Expand Up @@ -683,7 +688,7 @@ date.toLocaleString('en-US-u-nu-fullwide'); // => '8/24/2006'

### date.**toJSON**() : string

**Returns:** a string in the ISO 8601 date format representing `date`.
**Returns:** a string in the RFC 9557 date format representing `date`.

This method is the same as `date.toString()`.
It is usually not called directly, but it can be called automatically by `JSON.stringify()`.
Expand Down
15 changes: 10 additions & 5 deletions docs/plaindatetime.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,16 @@ Default values for other missing fields are determined by the calendar.
If the `calendar` property is not present, it's assumed to be `'iso8601'` (identifying the [ISO 8601 calendar](https://en.wikipedia.org/wiki/ISO_8601#Dates)).
Any other missing properties will be assumed to be 0 (for time fields).

If the value is not an object, it must be a string, which is expected to be in ISO 8601 format.
If the value is not an object, it must be a string, which is expected to be in RFC 9557 format, or a subset of that format that includes at least the date portion.
Time zone or UTC offset information will be ignored, with one exception: if a string contains a `Z` in place of a numeric UTC offset, then a `RangeError` will be thrown because interpreting these strings as a local date and time is usually a bug. `Temporal.Instant.from` should be used instead to parse these strings, and the result's `toZonedDateTimeISO` method can be used to obtain a timezone-local date and time.

Note that ISO 8601 and RFC 3339 formats are also subsets of RFC 9557, so will also work.
Temporal additionally accepts a few ISO 8601 extensions that RFC 9557 does not, like the use of 6-digit years.
For more info, see [RFC 9557 / ISO 8601 Grammar](https://tc39.es/proposal-temporal/#sec-temporal-iso8601grammar).

In unusual cases of needing date or time components of `Z`-terminated timestamp strings (e.g. daily rollover of a UTC-timestamped log file), use the time zone `'UTC'`. For example, the following code returns a "UTC date": `Temporal.Instant.from(item).toZonedDateTimeISO('UTC').toPlainDate()`.

If the string isn't valid according to ISO 8601, then a `RangeError` will be thrown regardless of the value of `overflow`.
If the string isn't a valid subset of the RFC 9557 format, then a `RangeError` will be thrown regardless of the value of `overflow`.

The `overflow` option works as follows, if `item` is an object:

Expand All @@ -120,7 +124,7 @@ The `overflow` option is ignored if `item` is a string.
Additionally, if the result is earlier or later than the range of dates that `Temporal.PlainDateTime` can represent (approximately half a million years centered on the [Unix epoch](https://en.wikipedia.org/wiki/Unix_time)), then this method will throw a `RangeError` regardless of `overflow`.

> **NOTE**: Although Temporal does not deal with leap seconds, dates coming from other software may have a `second` value of 60.
> In the default `'constrain'` mode and when parsing an ISO 8601 string, this will be converted to 59.
> In the default `'constrain'` mode and when parsing an RFC 9557 string, this will be converted to 59.
> In `'reject'` mode, this function will throw, so if you have to interoperate with times that may contain leap seconds, don't use `'reject'`.

> **NOTE**: The allowed values for the `item.month` property start at 1, which is different from legacy `Date` where months are represented by zero-based indices (0 to 11).
Expand Down Expand Up @@ -833,7 +837,7 @@ dt1.equals(dt1); // => true
Valid values are `'ceil'`, `'floor'`, `'expand'`, `'trunc'`, `'halfCeil'`, `'halfFloor'`, `'halfExpand'`, `'halfTrunc'`, and `'halfEven'`.
The default is `'trunc'`.

**Returns:** a string in the ISO 8601 date format representing `datetime`.
**Returns:** a string in the RFC 9557 date format representing `datetime`.

This method overrides the `Object.prototype.toString()` method and provides a convenient, unambiguous string representation of `datetime`.
The string can be passed to `Temporal.PlainDateTime.from()` to create a new `Temporal.PlainDateTime` object.
Expand All @@ -846,6 +850,7 @@ Note that rounding may change the value of other units as well.

Normally, a calendar annotation is shown when `datetime`'s calendar is not the ISO 8601 calendar.
By setting the `calendarName` option to `'always'` or `'never'` this can be overridden to always or never show the annotation, respectively.
With `calendarName: 'never'` the output string will additionally be valid in the ISO 8601 and RFC 3339 date formats.
Normally not necessary, a value of `'critical'` is equivalent to `'always'` but the annotation will contain an additional `!` for certain interoperation use cases.
For more information on the calendar annotation, see [the `Temporal` string formats documentation](./strings.md#calendar-systems).

Expand Down Expand Up @@ -903,7 +908,7 @@ dt.toLocaleString('en-US-u-nu-fullwide-hc-h12'); // => '12/7/1995,

### datetime.**toJSON**() : string

**Returns:** a string in the ISO 8601 date format representing `datetime`.
**Returns:** a string in the RFC 9557 date format representing `datetime`.

This method is the same as `datetime.toString()`.
It is usually not called directly, but it can be called automatically by `JSON.stringify()`.
Expand Down
13 changes: 9 additions & 4 deletions docs/plainmonthday.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,16 @@ If the value is any other object, it:
If `month` is used and `calendar` is provided, then `year` must be provided as well because `month` is ambiguous in some calendars without knowing the year.
- May have a `calendar` property. If omitted, the [ISO 8601 calendar](https://en.wikipedia.org/wiki/ISO_8601#Dates) will be used by default.

If the value is not an object, it must be a string, which is expected to be in ISO 8601 format.
If the value is not an object, it must be a string, which is expected to be in RFC 9557 format, or a subset of that format that includes at least the month and day.
For the ISO 8601 calendar, only the month and day will be parsed from the string.
For other calendars, the year and calendar are also parsed in addition to month and day.
Any other parts of the string are optional and will be ignored.

If the string isn't valid according to ISO 8601, then a `RangeError` will be thrown regardless of the value of `overflow`.
Note that ISO 8601 and RFC 3339 formats are also subsets of RFC 9557, so will also work.
Temporal additionally accepts a few ISO 8601 extensions that RFC 9557 does not, like the use of 6-digit years.
For more info, see [RFC 9557 / ISO 8601 Grammar](https://tc39.es/proposal-temporal/#sec-temporal-iso8601grammar).

If the string isn't a valid subset of the RFC 9557 format, then a `RangeError` will be thrown regardless of the value of `overflow`.
A `RangeError` will also be thrown for strings that contain a `Z` in place of a numeric UTC offset, because interpreting these strings as a local date is usually a bug.

The `overflow` option works as follows, if `item` is an object:
Expand Down Expand Up @@ -254,13 +258,14 @@ md2.equals({ monthCode: 'M02', day: 29 }); // => true
Valid values are `'auto'`, `'always'`, `'never'`, and `'critical'`.
The default is `'auto'`.

**Returns:** a string in the ISO 8601 date format representing `monthDay`.
**Returns:** a string in the RFC 9557 date format representing `monthDay`.

This method overrides the `Object.prototype.toString()` method and provides a convenient, unambiguous string representation of `monthDay`.
The string can be passed to `Temporal.PlainMonthDay.from()` to create a new `Temporal.PlainMonthDay` object.

Normally, a calendar annotation is shown when `monthDay`'s calendar is not the ISO 8601 calendar.
By setting the `calendarName` option to `'always'` or `'never'` this can be overridden to always or never show the annotation, respectively.
With `calendarName: 'never'` the output string will additionally be valid in the ISO 8601 and RFC 3339 date formats.
Normally not necessary, a value of `'critical'` is equivalent to `'always'` but the annotation will contain an additional `!` for certain interoperation use cases.
For more information on the calendar annotation, see [the `Temporal` string formats documentation](./strings.md#calendar-systems).

Expand Down Expand Up @@ -314,7 +319,7 @@ md.toLocaleString(`en-US-u-nu-fullwide-ca-${calendar}`); // => '8/24'

### monthDay.**toJSON**() : string

**Returns:** a string in the ISO 8601 date format representing `monthDay`.
**Returns:** a string in the RFC 9557 date format representing `monthDay`.

This method is the same as `monthDay.toString()`.
It is usually not called directly, but it can be called automatically by `JSON.stringify()`.
Expand Down
14 changes: 9 additions & 5 deletions docs/plaintime.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,14 @@ Any missing ones will be assumed to be 0.

If the `calendar` property is present, it must be the string `'iso8601'` or the [ISO 8601 calendar](https://en.wikipedia.org/wiki/ISO_8601#Dates), for future compatibility.

If the value is not an object, it must be a string, which is expected to be in ISO 8601 format.
If the string designates a date, it will be ignored.
If the value is not an object, it must be a string, which is expected to be in RFC 9557 format, or a subset of that format that includes at least the time.
If the string designates a date, the date will be ignored.
Time zone or UTC offset information will also be ignored, with one exception: if a string contains a `Z` in place of a numeric UTC offset, then a `RangeError` will be thrown because interpreting these strings as a local time is usually a bug. `Temporal.Instant.from` should be used instead to parse these strings, and the result's `toZonedDateTimeISO` method can be used to obtain a timezone-local date and time.

Note that ISO 8601 and RFC 3339 formats are also subsets of RFC 9557, so will also work.
Temporal additionally accepts a few ISO 8601 extensions that RFC 9557 does not, like the use of 6-digit years.
For more info, see [RFC 9557 / ISO 8601 Grammar](https://tc39.es/proposal-temporal/#sec-temporal-iso8601grammar).

In unusual cases of needing date or time components of `Z`-terminated timestamp strings (e.g. daily rollover of a UTC-timestamped log file), use the time zone `'UTC'`. For example, the following code returns a "UTC time": `Temporal.Instant.from(item).toZonedDateTimeISO('UTC').toPlainTime()`.

The `overflow` option works as follows, if `item` is an object:
Expand All @@ -76,7 +80,7 @@ The `overflow` option is ignored if `item` is a string.
> **NOTE**: Although Temporal does not deal with leap seconds, times coming from other software may have a `second` value of 60.
> In the default `'constrain'` mode, this will be converted to 59.
> In `'reject'` mode, the constructor will throw, so if you have to interoperate with times that may contain leap seconds, don't use `'reject'`.
> However, if parsing an ISO 8601 string with a seconds component of `:60`, then it will always result in a `second` value of 59, in accordance with POSIX.
> However, if parsing an RFC 9557 string with a seconds component of `:60`, then it will always result in a `second` value of 59, in accordance with POSIX.

Example usage:

Expand Down Expand Up @@ -474,7 +478,7 @@ time.equals(time); // => true
Valid values are `'ceil'`, `'floor'`, `'expand'`, `'trunc'`, `'halfCeil'`, `'halfFloor'`, `'halfExpand'`, `'halfTrunc'`, and `'halfEven'`.
The default is `'trunc'`.

**Returns:** a string in the ISO 8601 time format representing `time`.
**Returns:** a string valid in the RFC 9557, ISO 8601, and RFC 3339 time formats representing `time`.

This method overrides the `Object.prototype.toString()` method and provides a convenient, unambiguous string representation of `time`.
The string can be passed to `Temporal.PlainTime.from()` to create a new `Temporal.PlainTime` object.
Expand Down Expand Up @@ -527,7 +531,7 @@ time.toLocaleString('en-US-u-nu-fullwide-hc-h24'); // => '19:39:09'

### time.**toJSON**() : string

**Returns:** a string in the ISO 8601 date format representing `time`.
**Returns:** a string in the RFC 9557 and ISO 8601 time format representing `time`.

This method is the same as `time.toString()`.
It is usually not called directly, but it can be called automatically by `JSON.stringify()`.
Expand Down
Loading
Loading