tc39 / proposal-intl-duration-format

https://tc39.es/proposal-intl-duration-format
MIT License
163 stars 18 forks source link

Proposal for Intl.DurationFormat

Stage: 3

Champion: Younies Mahmoud, Ujjwal Sharma

Authors: Younies Mahmoud, Ujjwal Sharma

Stage 3 Reviewers

Resources

Status

Overview

Quick Start

new Intl.DurationFormat("fr-FR", { style: "long" }).format({
    hours: 1,
    minutes: 46,
    seconds: 40,
});
// => "1 heure, 46 minutes et 40 secondes"

Motivation

Requirements & Design

In this section, we are going to illustrate each user needs (requirements) and a design for each need (requirement)

Supported Duration Units

Design

Input Value

Design

Formatting width

Users want to determine several types of the formatting width as following

Format width Example
Long 1 hour and 50 minutes
Short 1 hr, 50 min
Narrow 1h 50m
Digital 1:50:00

Design

Determining Duration Units

DurationFormat does not do any arithmetic operations nor rounding on the input implicitly. Instead, the user must edit the input to ensure the input is within the desired range.

To avoid accidentally omitting part of the duration, DurationFormat always outputs all nonzero fields (except sub-second fields truncated by fractionalDigits). Callers who want to omit nonzero fields (for example, only showing the date or time portion of the duration) should edit the input duration.

Design

    const duration = { hours: 1, minutes: 2, seconds: 33 };

Hide zero-value fields

In most cases, users want to avoid displaying zero-value fields. All zero-valued fields are hidden by default. If you specify the style for a specific field, then it is always displayed, but you can override that behavior by also setting the display option for that particular field to "auto" again explicitly.

Design

For each field foo, there is an option fooDisplay that is set to "auto" by default. Setting that option to "always" causes that field to be displayed even if it is zero; for example, to always show the "day" field, set { dayDisplay: "always" }. If you specify the style for that field by setting the foo option, then the default for fooDisplay becomes "always"; for example, { day: "short" } implies { day: "short", dayDisplay: "always" }.

Locale-aware format

Design

Adding the locale in string format as a first argument, or specifying a ranked list of locales as an array of string values.

Display fractional values

Sometimes it is desirable to display the smallest sub-second unit not by itself but as a fraction of the immediately larger unit.

Design

We allow users to specify a fractionalDigits option that will display the smallest sub-second unit with display set to "auto" as a fraction of the previous unit if it is non-zero and if these values have style set to "numeric". The number of digits used will be the value passed to this option. By default fractionalDigits is undefined. In this case, exactly as many fractional digits as needed to display the whole duration are included. If rounding is necessary, we round toward 0.

Example


const duration = { seconds: 12, milliseconds: 345, microseconds: 600 } ;

new Intl.DurationFormat('en', { style: "digital", fractionalDigits: 2 }).format(duration); 
// "0:00:12.35"

new Intl.DurationFormat('en', { seconds: "numeric", fractionalDigits: 2 }).format(duration); 
// "12.35"

> new Intl.DurationFormat('en', { seconds: "numeric", fractionalDigits: 5 }).format(duration); 
// "12.34560"

> new Intl.DurationFormat('en', { seconds: "numeric"}).format(duration); 
// "12.3456"

API design

Constructor

Syntax

new Intl.DurationFormat(locales, options)

Parameters

Default values

Notes

Intl.DurationFormat#format

Syntax

new Intl.DurationFormat('en').format(duration)

Parameters

Returns

A string containing the formatted duration.

Intl.DurationFormat#formatToParts

Syntax

new Intl.DurationFormat('en').formatToParts(duration)

Parameters

Returns

An Array<{type: string, value: string}> containing the formatted duration in parts.

Implementation Status

V8 Prototypes

Three v8 prototypes (try to use two different possible ICU classes) were made, ALL are:

  1. Base the implementation on icu::MeasureFormat::formatMeasures()
  2. Based on the support of "-and-" unit in LocalizedNumberFormatter
  3. Based on icu::ListFormatter and icu::number::LocalizedNumberFormatter w/o depend on the "X-and-Y" units.