Skip to content

format="micro" ignores threshold and has no tense support  #353

@maxbeizer

Description

@maxbeizer

Problem

We want compact relative timestamps on GitHub Issues — "2w ago" for recent items, falling back to absolute dates ("Jan 1, 2024") for items older than 30 days. The natural API for this would be:

<relative-time format="micro" tense="past" threshold="P30D" datetime="2024-01-01T00:00:00Z" />

But today this doesn't work because there are two related gaps in format="micro":

  1. threshold is ignored for format="micro"resolveFormat() returns 'duration' unconditionally for micro, never checking whether an explicitly configured threshold should switch the element to absolute datetime output. Old dates therefore render as micro durations like "6mo" or "2yr".

  2. micro output cannot include tense phrasinggetDurationFormat() returns only the compact duration string, so consumers cannot get "2w ago" or "in 3d" from the component alone.

Current workaround (and why it's bad)

Consumers are forced to add a separate suffix element outside the component:

const MODULE_LOAD_TIME = Date.now()
const THIRTY_DAYS_MS = 30 * 86_400_000

// in render:
<RelativeTime format="micro" datetime={createdAt} threshold="P30D" />
{new Date(createdAt).getTime() > MODULE_LOAD_TIME - THIRTY_DAYS_MS && <span> ago</span>}

This has several problems:

  • Desync: The web component live-updates on a timer with Date.now(), but the external suffix is keyed to a stale timestamp captured at module load. At the threshold boundary, they disagree — producing either "Jan 1, 2024 ago" or "4w" (no ago).
  • User preference: Users who set data-prefers-absolute-time="true" get the component's absolute date plus the hardcoded suffix: "Jan 01, 2020, 08:02:03 PM ago".
  • DRY: The workaround has to be duplicated in every component that uses compact timestamps.
  • Threshold doesn't actually work: As noted above, threshold="P30D" is silently ignored for micro, so old items show "6mo" instead of an absolute date.

Proposed behavior

1. format="micro" should support explicit threshold

When a threshold attribute is explicitly provided and the elapsed duration exceeds that threshold, format="micro" should fall back to datetime format (absolute date). This gives consumers an opt-in API for compact recent timestamps with absolute old timestamps:

<relative-time format="micro" tense="past" threshold="P30D" datetime="..." />

Important compatibility note: threshold defaults to P30D, but existing format="micro" consumers may rely on old dates continuing to display as "6mo" / "2y". To avoid surprising them, I think micro should only honor threshold when the threshold attribute is explicitly present.

2. format="micro" should support tense phrasing

When rendering micro duration output:

  • tense="past" should render "2w ago"
  • tense="future" should render "in 3d"
  • tense="auto" should preserve the current compact output, e.g. "2w"

This should avoid requiring every consumer to compose a separate suffix/prefix outside the web component.

One open question: because micro uses localized duration formatting, should the tense wrapper also be localized rather than hardcoded English "ago" / "in "? GitHub Issues likely wants English-style compact output here, but the package-level behavior should be explicit.

3. User absolute date preference

shouldDisplayUserPreferredAbsoluteTime() currently returns false for resolved format === 'duration'. Since format="micro" currently resolves to duration, it cannot distinguish true duration output from micro output.

For this.format === 'micro', the user preference should be respected so data-prefers-absolute-time="true" displays the user-preferred absolute date instead of a compact duration.

Expected usage after this change

<!-- "2w ago" for recent, "Jan 1, 2024" for old, respects user prefs -->
<relative-time format="micro" tense="past" threshold="P30D" datetime="..." />

No wrapper elements. No stale timestamps. No desync. Live-updates correctly.

Compatibility / implementation notes

Because these gaps have different risk profiles, we may want to split this into two issues or PRs:

  1. Micro threshold support: compatibility-safe if limited to explicitly provided threshold attributes, and directly fixes the old-date fallback problem.
  2. Micro tense phrasing: needs an API/i18n decision because "ago" / "in" wrappers may need localization or may intentionally be GitHub-specific English compact UI.

Tests should cover:

  • format="micro" threshold="P30D" falls back to datetime after 30 days.
  • format="micro" without an explicit threshold preserves existing old-date behavior.
  • format="micro" tense="past" renders recent past values like "2w ago".
  • format="micro" tense="future" renders recent future values like "in 3d".
  • format="micro" respects data-prefers-absolute-time="true".

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions