Skip to content

precision="year" on duration/elapsed format is ignored — falls back to full millisecond precision #366

Description

@r1m

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;

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions