Version
5.3.0
Affected file
src/duration.ts (compiled: dist/duration.js), function elapsedTime()
Description
Setting precision="year" on a <relative-time> (or <time-ago>) element with format="duration" (or format="elapsed") does not limit the output to years — instead it renders the full duration breakdown down to milliseconds, as if no precision had been set at all.
Reproduction
<relative-time datetime="2023-06-23T08:38:34.578Z" format="duration" precision="year">
</relative-time>
Expected: 3 years
Actual: 3 years, 1 month, 21 days, 10 minutes, 56 seconds, 181 milliseconds
Every other precision value (month, day, hour, minute, second) works correctly and truncates the output as documented.
Root cause
In elapsedTime():
export function elapsedTime(date, precision = 'second', now = Date.now()) {
// ...
const i = unitNames.indexOf(precision) || unitNames.length;
// ...
}
unitNames is ['year', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'].
unitNames.indexOf('year') returns 0. Since 0 is falsy in JavaScript, the || operator treats it as "not found" and falls back to unitNames.length (8), which effectively means "no truncation — include every unit down to milliseconds."
Suggested fix
Use a strict check for "not found" instead of relying on truthiness:
const idx = unitNames.indexOf(precision);
const i = idx === -1 ? unitNames.length : idx;
Version
5.3.0
Affected file
src/duration.ts(compiled:dist/duration.js), functionelapsedTime()Description
Setting
precision="year"on a<relative-time>(or<time-ago>) element withformat="duration"(orformat="elapsed") does not limit the output to years — instead it renders the full duration breakdown down to milliseconds, as if noprecisionhad been set at all.Reproduction
Expected:
3 yearsActual:
3 years, 1 month, 21 days, 10 minutes, 56 seconds, 181 millisecondsEvery other precision value (
month,day,hour,minute,second) works correctly and truncates the output as documented.Root cause
In
elapsedTime():unitNamesis['year', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'].unitNames.indexOf('year')returns0. Since0is falsy in JavaScript, the||operator treats it as "not found" and falls back tounitNames.length(8), which effectively means "no truncation — include every unit down to milliseconds."Suggested fix
Use a strict check for "not found" instead of relying on truthiness: