Intl.DurationFormat
zbraniecki opened this issue ยท 18 comments
Since there's little progress with deciding on what to do with durations, and ICU's API doesn't seem too defined about it, I'd like to start a discussion about possible choices. It seems to me that we have four:
- We can add it to NumberFormat
- We can add it to UnitFormat
- We can create a separate DurationFormat
- We can kickstart some RuleBasedNumberFormat
The common use cases are:
- Timer "05:12:21"
- Stopwatch "12:21.05"
- Video/Music player remaining/elapsed time "-04:13"
The formatting differs from time formatter, because the UI will define the range of units to be displayed, like h:m:s
, m:s.S
and the number of digits per unit (m:ss
vs mm:ss
or mm:ss.SSS
vs mm:ss.SS
)
NumberFormat
would be convenient for that reason - it would benefit from similar API of defining minimumIntegerDigits
and maximumIntegerDigits
for each component, and the value itself may be just a number of milliseconds.
Fitting it into UnitFormat
seems to be natural fit for CLDR Unit Elements [0] together with compound units
, unit sequences
and coordinate units
, but may be hard and requiring us to bend over backward to accommodate for the options that will be required.
Custom DurationFormat
seems to be the easiest choice from the API design perspective, but it increases the number of objects we specify. It's been the choice I made so far for Firefox OS patterns, but I'll be happy to migrate our code once we reach a consensus here.
RuleBasedNumberFormat
is what ICU seems to be using now for duration patterns, but it's a pretty big API most similar to Mozilla's proprietary Date.prototype.toLocaleFormat
and I'm not sure if we want to go there.
The API I use in DurationFormat
looks like this:
var f = Intl.DurationFormat(locales, {
minUnit: 'second', // millisecond | second | minute | hour
maxUnit: 'hour' // millisecond | second | minute | hour
});
f.format(i); // 52:34:51
Thougths?
[0] http://www.unicode.org/reports/tr35/tr35-general.html#Unit_Elements
Brainstorming... Follow an API variation that is more parallel with DateTimeFormat for picking different field lengths:
var f = Intl.DurationFormat(locales, {
hour: 'numeric',
minute: '2-digit'
});
f.format(i); // 8:01
CLDR provides data for three combinations: hm
(hour and minute), hms
(hour, minute, and second), and ms
(minute and second). AFAIK, it provides no algo for dynamically including additional fields, e.g., milliseconds. (cc @srl295?)
- http://www.unicode.org/reports/tr35/tr35-general.html#durationUnit
- https://github.com/unicode-cldr/cldr-units-modern/blob/master/main/en/units.json#L2046-L2054
From those skeletons, the default length can be extracted. For example, {hm: "h:mm"}
means the default for hour is numeric
and the default for minutes is 2-digits
.
Heads up, this has been advanced to Stage 0 as of today.
@srl295 - We will need {mm}:{ss}.{SS}
at the very least for all kind of timers. (Android, iPhone timers show milliseconds). Can we get it into CLDR?
Alternatively, we could just encode a single pattern, like {hh}:{mm}:{ss}.{SS}
that we "cut out" from the portion that we need.
This proposal has been advanced to Stage 1 as of today.
@zbaniecki see http://apps.icu-project.org/icu4jweb/flexTest.jsp?pat=HmsSS&_=en_US
skeleton HmsSS
--> pattern HH:mm:ss.SS
--> format 14:02:01.34
and in Polish HH:mm:ss,SS
/ 14:02:41,67
so the data / algo is there, let me know if this helps
thanks! Where is this skeleton in CLDR?
@srl295 - So I assume that flexTest indicates that it's something around the algo to get from skeleton to pattern using this: http://www.unicode.org/cldr/charts/29/summary/en.html#1746 - but I don't see anything on SS
token there :( (and the value for polish is likely wrong, it should be ss.SS
, not ss,SS
)
@zbraniecki two problems:
- CLDR spec is unclear AND/OR CLDR data is incomplete.
- ICU has special behavior AND meta data that's not in CLDR
Filed a CLDR bug here http://unicode.org/cldr/trac/ticket/9352
@srl295, as you pointed out earlier, CLDR/ICU has support for measure format that can be used for duration format. Then, the thread moved to talk about skeletons for DateTime format.
The input to DateTime format is 'time' while the input for duration format is 'time delta'.
Can skeletons/patterns for the DateTime format be used for measure format?
@jungshik - I don't see measure format skeletons useful for duration format.
Also, CLDR bug for fractional seconds has been assigned to target CLDR 30 which should unblock us here. (http://unicode.org/cldr/trac/ticket/9352)
Are there plans to support formatToParts()
for this? Seems like a natural extension, and that possibility seems to weigh on the side of having a whole separateDurationFormatter
.
A first-class Duration object is being added in Temporal. This ECMA-402 proposal for duration formatting needs to be prioritized.
Possible suggestion: since we are generally moving in the direction of overloading Intl constructor functionality that share similar options, I am wondering if this would be appropriate as a new method on Intl.DateTimeFormat, similar to Intl.DateTimeFormat.prototype.formatRange (CC @fabalbon).
For example,
const duration = new Temporal.Duration(...);
const fmt = new Intl.DateTimeFormat("en-US", {
minute: "2-digit",
second: "2-digit",
fractionalSecondDigits: 3
});
console.log(fmt.formatDuration(duration));
// "01:23.456"